我试图了解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 }
它无法正常工作,当然因为我不知道如何推进普查员。有人可以帮助我理解我如何实现它吗?
答案 0 :(得分:2)
您应该使用 continuation 的某种机制。检查:
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
此外,实现带有光纤的枚举器应该是非常简单的(但如果你想了解整个事情,可能它们太“高级”,那么尝试使用continuation):
答案 1 :(得分: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