【问题标题】:How can I get source and variable values in ruby tracebacks?如何在 ruby​​ 回溯中获取源值和变量值?
【发布时间】:2010-09-11 12:55:00
【问题描述】:

这是典型 Rub​​y on Rails 回溯的最后几帧:

以下是 Python 中典型的 Nevow 回溯的最后几帧:

也不只是web环境,你可以在ipython和irb之间做类似的比较。如何在 Ruby 中获得更多此类细节?

【问题讨论】:

    标签: ruby debugging exception traceback


    【解决方案1】:

    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 就应该能够工作,尽管可能很慢。)

    更新

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-05
      • 1970-01-01
      • 2017-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多