Tracing global variables in Ruby using trace_var
Recently, I came across this “interesting” approach to printing the “99 bottles of beer” song on Rosetta code.
This is unlike any Ruby code I’ve seen before.
What are those global variables doing?
Let’s start by looking at this
Controls tracing of assignments to global variables.
… the block is executed whenever the variable is assigned. The block or Proc object receives the variable’s new value as a parameter.
Let’s try something simple with this.
If you pass in a string instead of a block or Proc, it gets eval’ed.
If you need to unset tracing with
you can do
Now that we’ve seen how
let’s go back to the “99 bottles” program.
It’s starting to make sense now.
This assigns the string
$bottle_num is zero,
in which case “No more bottles”
So each time
$bottle_num gets changed,
$bottles string gets updated automatically.
trace_var can be a useful debugging tool.
Suppose you want to find out
which line of code is
changing a global variable.
You could do this:
This will show you assigned value and the execution stack at that point.
But if you ever find yourself debugging your code like this, maybe it’s a good time to get rid of those global variables. They are bad for your codebase.
trace_var only works with global variables.
If you need a more flexible tool
you might want to look at Ruby 2.0’s new
More weird Ruby
If you found this post interesting, you might also enjoy my other articles about lesser known features of Ruby, such as the flip flop operator, tail call optimization, memoization using metaprogramming tricks, or using Ruby as an alternative to sed/awk.