加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 19:04:48 所属栏目:百科 来源:网络整理
导读:这是典型的 Ruby on Rails回溯的最后几帧: application trace http://img444.imageshack.us/img444/8990/rails-lastfew.png 以下是Python中典型的Nevow回溯的最后几帧: alt text http://img444.imageshack.us/img444/9173/nw-lastfew.png 它不仅仅是网络环
这是典型的 Ruby on Rails回溯的最后几帧:
application trace http://img444.imageshack.us/img444/8990/rails-lastfew.png

以下是Python中典型的Nevow回溯的最后几帧:
alt text http://img444.imageshack.us/img444/9173/nw-lastfew.png

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

解决方法

AFAIK曾经被捕获过,因此抓住它被引发的背景为时已晚.如果你捕获异常的新调用,你可以使用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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读