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