当使用Proc.new v。&符号时,为什么ruby中的break语句表现不同?

块的break语句( 根据Ruby Programming Language )定义如下:

它导致块返回到它的迭代器,迭代器返回到调用它的方法。

因此,当运行以下代码时,它会导致LocalJumpError。

def test puts "entering test method" proc = Proc.new { puts "entering proc"; break } proc.call # LocalJumpError: iterator has already returned puts "exiting test method" end test 

虽然以下代码不会抛出LocalJumpError。 &符号有什么特别之处? &符号是否隐含使用Proc.new?

 def iterator(&proc) puts "entering iterator" proc.call # invoke the proc puts "exiting iterator" # Never executed if the proc breaks end def test iterator { puts "entering proc"; break } end test 

换句话说,我读了&符号作为进入Proc.new呼叫的手段。 此时行为应该与第一个代码段相同。

 def iterator (p = Proc.new { puts "entering proc"; break}) ... end 

免责声明 :我是新手学习语言(ruby 1.9.2),因此会欣赏参考资料和详细的概要。

break使块块的调用者返回。 在以下代码中:

 proc = Proc.new { break } 

转换为Proc对象的块的“调用者”是Proc.new。 break应该使块的调用者返回,但Proc.new已经返回。

在这段代码中:

 def iterator(&b); b.call; end iterator { break } 

块的调用者是iterator ,因此它使iterator返回。

这是答案 。

Ampersand用于将proc转换为块,将块转换为proc。

我更改了示例,以便与您的案例相关:

 def run_my_code(&my_code) puts 'before proc' my_code.call puts 'after proc' end run_my_code { puts "passing a block, accepting a proc"; break} => before proc passing a block, accepting a proc 

你可以看到它没有达到’后处理’

 def run_my_code yield end my_proc = Proc.new { puts "passing a proc instead of block"; break} run_my_code &my_proc => passing a proc instead of block LocalJumpError: break from proc-closure from (pry):75:in `block in 
'

在你的第二个例子中,你有一个结果中的proc,proc从iterator中断并返回test函数。

 def iterator(&proc) puts 'entering iterator' proc.call puts 'exiting iterator' end def test puts 'before test' iterator { puts 'entering proc'; break } puts 'after test' end =>before test entering iterator entering proc after test 

它与块,触发器和lambdas之间的区别 – 以及它们各自的范围有关。

我在2009年写了一篇关于它的文章,你可能会发现它很有用: http : //www.leonardoborges.com/writings/2009/07/22/procs-lambdas-blocks-whats-the-difference/

希望这可以帮助。