块的break语句(根据The 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),因此会非常感谢参考资料和详细的概要。
答案 0 :(得分:7)
break
使块和块的调用者返回。在以下代码中:
proc = Proc.new { break }
转换为Proc对象的块的“调用者”是Proc.new。 break
应该使块的调用者返回,但Proc.new已经返回。
在此代码中:
def iterator(&b); b.call; end
iterator { break }
该区块的来电者为iterator
,因此会iterator
返回。
答案 1 :(得分:3)
这是answer。
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
正如你所看到的那样,它没有达到''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 <main>'
在你的第二个例子中,你有一个结果中的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
答案 2 :(得分:0)
它与块,触发器和lambdas之间的区别 - 以及它们各自的范围有关。
我在2009年写了一篇关于它的文章,你可能觉得它很有用:http://www.leonardoborges.com/writings/2009/07/22/procs-lambdas-blocks-whats-the-difference/
希望这有帮助。