Trace local variable

Hi !

I’ve searched a lot to get an answer but I can’t figured it out. I wish
to trace local variables in a method. Here is an example:

def test
a = 1
b = 2
end

Returns:
Variable a gets the value 1 in test
Variable b gets the value 2 in test

So, I’d like this output without adding some extra stuff in my method
test. I need a callback or thing like that but I can’t find it.

I’m aware of the built-in method trace_var, but unfortunately, it’s all
about global variables. So, I successed to trace attribute calls,
because it is possible to define methods like this:

def attribute=(value)

end

I also successed to trace method calls.

I’ve seen function like set_trace_func but it’s not really convenient to
deal with my particular problem. And it isn’t possible to redefine the
assignment operator = on its own.

Any ideas to trace local variables ?
Thanks !

2010/2/23 Onionwushu O. [email protected]:

Variable b gets the value 2 in test
end

I also successed to trace method calls.

I’ve seen function like set_trace_func but it’s not really convenient to
deal with my particular problem. And it isn’t possible to redefine the
assignment operator = on its own.

Any ideas to trace local variables ?

I don’t think there is an easy way with MRI and standard tools. You
could debug the code of course. Other than that, these are things
that I can imagine to work:

  • patch interpreter to generate output for variable access
  • use set_trace_func along with a parsed version of the source (e.g.
    ParseTree)
  • patch interpreter even more to allow for a similar mechanism like
    set_trace_func (aka “set_trace_local”).

Btw, why do you need that feature? If your methods are so complex
that you need tracing of individual variables maybe your methods are
too long.

Kind regards

robert

Thank you for your proposals. I’ll prefer to avoid patching the
interpreter for now :stuck_out_tongue:
I need this feature because I’d like to know each time a local variable
is updated. So, I found a way using set_trace_func and the binding
attribute, here it is:

set_trace_func lambda { |event, file, line, id, binding, classname|
if event == “line” or event == “return”
local = eval(“local_variables”, binding)
local.each do |l|
puts “#{l} : #{eval(l, binding)}”
end
puts “======”
end
}

I suppose this is not really nice about performance, but it’s working :stuck_out_tongue:

But that looks ugly :frowning:

I can not believe ruby could make it so difficult just to be able to
trace local variables? It’s a lot easier with global variables, but I
usually don’t use many global variables …