枚举器新增和收益率

时间:2016-03-06 11:35:25

标签: ruby

在ruby docs,我找到了这段代码:

fib = Enumerator.new do |y|
  a = b = 1
  loop do
    y << a
    a, b = b, a + b
  end
end

我无法理解它的作用。一般来说,它会计算斐波纳契数,但我很难理解细节。什么是y (Enumerator::Yielder)docs对此一无所知。 <<方法有什么作用? (我知道它的产量别名)。为什么在y << a时会发生无限循环 被删除了?谢谢!

1 个答案:

答案 0 :(得分:2)

请考虑以下代码:

fib = Enumerator.new do |y| 
  puts "Enter enumerator"
  a = b = 1 
  loop do
    puts "Inside loop"
    y << a
    puts "y: #{y.inspect}, a: #{a}, b: #{b}"
    a, b = b, a + b 
  end 
end
puts fib.take(5)

打印:

# Enter enumerator
# Inside loop
# y: #<Enumerator::Yielder:0x000000059a27e8>, a: 1, b: 1
# Inside loop
# y: #<Enumerator::Yielder:0x000000059a27e8>, a: 1, b: 2
# Inside loop
# y: #<Enumerator::Yielder:0x000000059a27e8>, a: 2, b: 3
# Inside loop
# y: #<Enumerator::Yielder:0x000000059a27e8>, a: 3, b: 5
# Inside loop

# 1
# 1
# 2
# 3
# 5

显然,这个输出实际上给出了你所说的所有问题的提示。请注意,我们只输入了一次一次。让我们深入研究:

为什么loop是无限的?

因为Fibonacci的数字序列是无限的。此枚举器旨在与Enumerable#take一起使用(请参阅上面的示例。)

什么是Enumerator::Yielder

这是一种抽象。它的方法yield实际上回调了被调用者的块,将参数作为块参数传递。

<<方法有什么作用?

产量一次。换句话说,它回调调用者代码,将其参数传递给调用者的块。在此特定示例中,它将回调each块,从a实例传递Yielder作为块参数(e,因为我将其命名为。)

为什么在删除y << a时会发生无限循环?

因为没有yield发生。在我的例子中,被叫方将在屈服五(take)次参数5后停止。