如何实现基本的枚举器类?

发布于 2024-12-09 19:47:32 字数 426 浏览 1 评论 0原文

我试图了解枚举器类的工作原理。具体来说,我不知道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 }

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

I am trying to understand how Enumerator class works. Specifically, I do not know how the yielder object is created and passed to the code block that the constructor takes.

Here is my first try:

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 }

It is not working, of course because I do not know how to advance the enumerator. Could somebody help me in understanding how I can implement it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心病无药医 2024-12-16 19:47:33

这是构建基本枚举器的一种方法(根据托克兰的建议更新):

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

Here's one way to build a basic enumerator (updated with tokland's suggestion):

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

  def next
    @fiber.resume
  end
end

Usage:

>> 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
放手` 2024-12-16 19:47:32

您应该使用某种延续机制。检查:

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

You should use some mechanism of continuation. Check:

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

Also, it should be pretty trivial to implement enumerators with fibers (but maybe they are too "high-level" if you want to understand the whole thing, try with continuations then):

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文