I would like to add some debugs for my simple ruby functions and I wrote a function as below,
def debug(&block)
varname = block.call.to_s
puts "#{varname} = #{eval(varname,block)}"
end
debug {:x} #prints x = 5
debug {:y} #prints y = 5
I understand that eval is evil. So I have two questions.
- Is there any way to write that debug method without using eval? If NO is there a preferred way to do this?
- Is there any way to pass a list of arguments to this method? I would ideally prefer debug {:x, :y. :anynumOfvariables}. I could not quite figure out how to factor that into the debug method (i.e, to take a list of arguments)
Just use arrays. You can use the
Arraymethod to ensure that you will always have an array, even if someone passes in only a single value:BTW: passing a block as the binding no longer works in Ruby 1.9. (Despite the fact that the documentation says it does work.) You have to explicitly call
Proc#bindingto get aBindingobject for thatProc:Fortunately, this already works in Ruby 1.8, so you can futureproof your code by including it.
An alternative would be to forgo the block altogether. I mean, you already force the user of the
debugto use the unfamiliar idiom of passing arguments in the block instead of in parentheses. Why not force them to just pass the binding instead?This has the added flexibility that they can actually pass a different binding than the one at the callsite, e.g. if they want to actually debug a piece of code in a different piece of the application.
BTW: here’s some fun with Ruby 1.9.2’s parameter introspection (
Proc#parameters):