Aha, I forgot about that one.
Say I want to display the arguments that each function gets. Could I
get that from a binding object?
Maybe this would do it (with the caveat noted):
class Binding
def locals
eval('local_variables',self).inject({}) do |hsh, var|
hsh[var.intern] = eval(var, self)
hsh
end
end
end
def foo(one, two = 'default')
'foo!'
end
def bar(*args)
'bar!'
end
def baz(arg = 7, &blk)
'baz!'
end
set_trace_func proc { |event, file, line, id, binding, classname|
if event == 'call'
puts "Called #{classname}.#{id} with args #{binding.locals.inspect}"
end
}
foo('arg')
foo('arg_one', 'arg_two')
bar
bar('these','are','my','args')
baz(4)
# NOTE: failure here, doesn't see the block
baz { |b| puts b }
baz(11, &proc { |b| puts b })
Output:
Called Object.foo with args {
ne=>"arg", :two=>"default"}
Called Object.foo with args {
ne=>"arg_one", :two=>"arg_two"}
Called Object.bar with args {:args=>[]}
Called Object.bar with args {:args=>["these", "are", "my", "args"]}
Called Object.baz with args {:arg=>4, :blk=>nil}
Called Object.baz with args {:arg=>7, :blk=>nil}
Called Object.baz with args {:arg=>11, :blk=>nil}
Also, the extensions/binding
(
http://extensions.rubyforge.org/rdoc/index.html) adds and changes the
binding, so you can just do:
bin = <a binding>
lvs = bin.local_variables.inject({}) { |hsh, v| hsh[v.intern] = bin[v];
hsh }
instead of modifying Binding yourself if you like, but I'm a bit confused
about the status of facets, extensions, and so on - not sure which are
current and which aren't
Cheers,