【问题标题】:Why does "block_given?" return false in debugger? (Works correctly when not debugging)为什么“block_given”?在调试器中返回 false? (不调试时正常工作)
【发布时间】:2011-12-09 08:20:13
【问题描述】:

在使用 ruby​​ 调试器进行测试时 block_given? 给出 false 但仍然执行,有人可以解释一下它是如何执行的吗?它与 context(是调试器吗?改变上下文)? 如果是,那么如何找到当前上下文。

现在在使用 pry 时代替 ruby-debug,然后 block_given? 返回 true

def test
  debugger
  if block_given?
    yield(4)
  else
    puts "ss"
  end
end
test {|el| puts "#{el}" }

【问题讨论】:

    标签: ruby ruby-debug pry


    【解决方案1】:

    这看起来像是 ruby​​-debug 中的一个错误,特别是 Kernel#binding_n,这是调试器正在使用的。

    您无需进入调试器读取/评估/打印循环即可查看错误。这是一个用 binding_n(0) 替换 debugger() 调用的非交互式示例:

    require 'rubygems'; require 'ruby-debug'
    Debugger.start
    def test
      puts eval("block_given?", binding_n(0))
      if block_given?
        yield(4)
      else
        puts "ss"
     end
    end
    test {|el| puts "#{el}" }
    

    Pry 没有这个问题可能是因为它使用了 Ruby 的 binding() 而不是 binding_n()。当然这是最靠谱的。

    在上面的例子中,这显然是一个胜利,因为 binding() 正是我们想要的。但与 Pry 一样棒的是,除了当前(或最近的)堆栈帧之外,它无法评估任何堆栈帧上下文中的表达式。

    另请参阅http://banisterfiend.wordpress.com/2011/01/27/turning-irb-on-its-head-with-pry/#comment-274,了解 Pry 和调试器(如 ruby​​-debug)之间的区别。

    最后,我会注意到我在修补后的 MRI 1.9.2 trepanning debuggerrbx-trepanning for Rubinius 1.2-ish 中都尝试过这个。

    它们都按预期工作。在这两种情况下,在 Ruby 运行时的更多帮助下,binding_n 的等价物以不同的方式完成。剩下的 rb8-trepanning 也存在错误,因为它也使用了 binding_n

    【讨论】:

    • 感谢您反复强调提出这一点。我怀疑绑定可能是问题的原因,但从不深挖谢谢伙计
    • @rocky,最近发布的 pry 插件可以让你在 Pry 会话中遍历堆栈:github.com/pry/pry-stack_explorer
    猜你喜欢
    • 2022-12-11
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    • 2014-02-28
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    相关资源
    最近更新 更多