1

我试图了解 Enumerator 类的工作原理。具体来说,我不知道 yielder 对象是如何创建并传递给构造函数所采用的代码块的。

这是我的第一次尝试:

class MyEnumerator
  def initialize(&block)
    @block = block
  end 
  def next()
    @block.call self
  end 
  def yield(*args)
    args
  end 
end


num_gen = MyEnumerator.new do |yielder|
  (1..10).each { |num| yielder.yield num }
end

5.times { p num_gen.next }

它不起作用,当然是因为我不知道如何推进枚举器。有人可以帮助我理解如何实现它吗?

4

2 回答 2

2

你应该使用一些延续机制。查看:

http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_c_continuation.html

http://ruby-doc.org/docs/ProgrammingRuby/html/ref_m_kernel.html#Kernel.callcc

此外,用纤维实现枚举器应该很简单(但如果你想了解整个事情,它们可能太“高级”,然后尝试使用延续):

http://www.ruby-doc.org/core-1.9.2/Fiber.html

于 2011-10-13T16:50:49.863 回答
1

这是构建基本枚举器的一种方法(根据 tokland 的建议进行了更新):

class MyEnumerator
  def initialize
    @fiber = Fiber.new { yield Fiber }
  end

  def next
    @fiber.resume
  end
end

用法:

>> num_gen = MyEnumerator.new { |f| (1..10).each { |x| f.yield x } }
=> #<MyEnumerator:0x007fd6ab8f4b28 @fiber=#<Fiber:0x007fd6ab8f4ab0>>
>> num_gen.next
=> 1
>> num_gen.next
=> 2
>> num_gen.next
=> 3
>> num_gen.next
=> 4
于 2011-10-13T16:55:51.923 回答