我最近开始阅读“Programming Ruby 1.9&2.0”一书。
它显示了显式枚举器的技巧

triangular_numbers = Enumerator.new do |yielder|
number = 0
count = 1
    loop do
        number += count
        count += 1
        yielder.yield number
    end
end
5.times { print triangular_numbers.next, " " }
puts

我想知道为什么这个 yielder.yield 会暂时离开循环并返回 number 的值,直到创建下一个枚举器对象。当循环块内的产量时,这似乎与通常的情况不同。查了APIdock,发现Proc.yield()的源码和Proc.call()是一样的。对于 Enumerator 类中的 Yielder 对象,Yielder 已经覆盖了 yield()。但是为什么 yielder.yield 会暂时离开循环块呢?

引用:
APIdock Yielder yield() ,
Ruby MRI rb_proc_call

最佳答案

您将 Ruby 的 yield 语句与 Enumerator::Yielder 的 yield 方法和 Proc 的 yield 方法混淆了。它们可能拼写相同,但它们完全不同。

陈述

yield 语句没有接收器。在方法中,它意味着“立即运行块”。如果没有附加块,则会发生错误。它并不总是给出参数,因为有时您只想运行块。

def foo
  yield :bar
end
foo # LocalJumpError
foo { |x| puts x } # bar

枚举器::Yielder

对于一个 yielder, yield 几乎总是被赋予一个参数。那是因为它的意思与 << 相同,即“下次有人对我调用 next 时,给他们这个值”。
Enumerator.new { |yielder| yielder.yield 3 }.next # 3
Enumerator.new { |yielder| yielder << 3 }.next # same thing

我认为使用 << 避免与 yield 语句混淆是个好主意。

进程

Procs 和 lambdas 基本上是函数。 yield 这里的意思与 call 相同,即“只调用函数”。您可以给它一个参数或不,这取决于 proc 的定义方式。这里没什么好看的。
proc { |x| puts x }.yield(:bar) # bar
proc { |x| puts x }.call(:bar) # same thing as previous line

我认为使用 call 避免与 yield 语句混淆是个好主意。

关于ruby - 枚举器 yielder.yield VS Proc.yield,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18865860/

10-11 09:18