gpt4 book ai didi

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

转载 作者:数据小太阳 更新时间:2023-10-29 06:59:32 24 4
gpt4 key购买 nike

这是典型的 Ruby on Rails 回溯的最后几帧: application trace

下面是 Python 中典型的 Nevow 回溯的最后几帧: alt text

也不仅仅是web环境,你可以对ipython和irb做类似的比较。我怎样才能在 Ruby 中获得更多此类详细信息?

最佳答案

据我所知,一旦捕获到异常,再获取引发异常的上下文就太晚了。如果捕获异常的新调用,则可以使用 evil.rb 的 Binding.of_caller 来获取调用范围,然后执行

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

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

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

更新

好的,我想通了。较长的代码如下:

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

关于ruby - 如何在 ruby​​ 回溯中获取源和变量值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/106920/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com