8

块的 break 语句(根据 Ruby 编程语言)定义如下:

它使块返回到它的迭代器,而迭代器返回到调用它的方法。

因此,当运行以下代码时,会导致 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),因此会欣赏参考资料和详细的概要。

4

3 回答 3

8

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

proc = Proc.new { break }

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

在这段代码中:

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

块的调用者是iterator,所以它iterator返回。

于 2012-01-24T22:13:46.773 回答
3

这是答案

& 符号用于将 proc 转换为 block 并将 block 转换为 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 <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
于 2012-01-17T02:43:30.300 回答
0

它与块、proc 和 lambda 之间的差异以及它们各自的范围有关。

我在 2009 年写了一篇关于它的帖子,您可能会觉得它很有用:http: //www.leonardoborges.com/writings/2009/07/22/procs-lambdas-blocks-whats-the-difference/

希望这可以帮助。

于 2012-01-17T03:22:37.913 回答