Enumerator对象如何跟踪其状态?

时间:2017-07-20 15:12:25

标签: ruby

Enumerator的实例如何跟踪其内部状态?以下面的代码段为例:

enum = Enumerator.new do |yielder|
  yielder << 1
  yielder << 2
  yielder << 3
end

puts enum.next # => 1
puts enum.next # => 2
enum.rewind # start again
puts enum.next # => 1

each上调用enum之类的迭代器方法时,每次调用each(或yielder#<<时,它会执行一次yielder#yield的阻止})。

我想要了解的是Ruby如何使next工作。它如何记住next值?它如何rewind回到第一个?如果我要编写一个基于next如何在Ruby中工作的基本实现,我该怎么做?

1 个答案:

答案 0 :(得分:2)

Enumerator在内部暂停执行并将控制权交给调用者。正如塞尔吉奥所说,它是基于光纤的,这是一个比线程更细粒度的执行单元。

纤维可以让你做到这一点:

def eat_more_fiber
  puts "In"
  Fiber.yield
  puts "Out"
end

f = Fiber.new do
  eat_more_fiber
end

f.resume
# Prints "In"
f.resume
# Prints "Out"

请注意,在第一个resume呼叫控制返回到该代码块之后。