为什么“block_given?”在调试器中返回false? (不调试时正常工作)

时间:2011-12-09 08:20:13

标签: ruby ruby-debug pry

使用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}" }

1 个答案:

答案 0 :(得分:3)

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

您无需进入调试器read / eval / print循环来查看错误。以下是使用 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 debugger以及rbx-trepanning for Rubinius 1.2-ish中尝试了这两种方法。

它们都按预期工作。在两者中, binding_n 的等价物在Ruby运行时的更多帮助下以不同方式完成。这留下了rb8-trepanning,它有bug,因为它也使用 binding_n