是否有可能从set_trace_func获取值?

时间:2013-03-15 16:32:38

标签: ruby tracing

我想写一些像这样的Ruby代码来查看每个被调用的方法返回的值(例如,来自脚本):

set_trace_func proc { |event, file, line, id, binding, classname|
  if event == "return"
    puts "returning #{return_value} from #{classname}.#{id}"
  end
}

这可能吗?我可以在上面的代码范围内以某种方式得到return_value吗?

2 个答案:

答案 0 :(得分:5)

Ruby 2.0有一个新的TracePoint类,其中包含return_value实例方法。您可以像这样使用它:

trace_point = TracePoint.new(:return) do |t| # event type specification is optional
  puts "returning #{t.return_value} from #{t.defined_class}.#{t.method_id}"
end

trace_point.enable

答案 1 :(得分:1)

如果有人仍然对1.9.3感兴趣,那么有一种方法可以做到这一点:

您可以使用eval(code, binding)set_trace_func处理程序中评估被调用函数,然后eval评估您已注意到的返回值。

您必须自己重新构建来电代码。 类似的东西:

arg_arr = []
params = eval('method(__method__).parameters', binding)
params.each do |param|
  case param[0]
        when :req, :opt
          arg_arr << param[1]
        when :rest
          arg_arr << '*' + param[1]
        else
          puts "Need handler for type #{param[0]}"
      end
end

call_expr = "#{id} #{arg_arr.join(',')}"
puts "Call with <#{call_expr}>"
res = eval(call_expr, binding)
puts "sub-method #{id} returned #{res}"
eval("return #{res.inspect}", binding)

您只能在一个级别下执行此操作,因为set_trace_func已在其处理程序的持续时间内关闭。此外,arguments的输出似乎没有记录。而且,它使用邪恶。