如何在ruby回溯中获取源和变量值?

这是典型的Ruby on Rails回溯的最后几帧: 应用程序跟踪http://img444.imageshack.us/img444/8990/rails-lastfew.png

以下是Python中典型的Nevow追溯的最后几帧: 替代文字http://img444.imageshack.us/img444/9173/nw-lastfew.png

它不仅仅是网络环境,你可以在ipython和irb之间进行类似的比较。 如何在Ruby中获得更多这类细节?

AFAIK曾经被捕获过,因此抓住它被引发的背景为时已晚。 如果你捕获exception的新调用,你可以使用evil.rb的Binding.of_caller来获取调用范围,并且

eval("local_variables.collect { |l| [l, eval(l)] }", Binding.of_caller) 

但这是一个非常大的黑客。 正确的答案可能是扩展Ruby以允许对调用堆栈进行一些检查。 我不确定是否有一些新的Ruby实现允许这样做,但我确实记得对Binding.of_caller的强烈反对,因为它会使优化变得更加困难。

(老实说,我不理解这种反弹:只要解释器​​记录了关于所执行的优化的足够信息,Binding.of_caller应该能够工作,尽管可能很慢。)

更新

好的,我明白了。 Longish代码如下:

 class Foo < Exception attr_reader :call_binding def initialize # Find the calling location expected_file, expected_line = caller(1).first.split(':')[0,2] expected_line = expected_line.to_i return_count = 5 # If we see more than 5 returns, stop tracing # Start tracing until we see our caller. set_trace_func(proc do |event, file, line, id, binding, kls| if file == expected_file && line == expected_line # Found it: Save the binding and stop tracing @call_binding = binding set_trace_func(nil) end if event == :return # Seen too many returns, give up. :-( set_trace_func(nil) if (return_count -= 1) <= 0 end end) end end class Hello def a x = 10 y = 20 raise Foo end end class World def b Hello.new.a end end begin World.new.b rescue Foo => e b = e.call_binding puts eval("local_variables.collect {|l| [l, eval(l)]}", b).inspect end