首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >枚举器yielder.yield与Proc.yield

枚举器yielder.yield与Proc.yield
EN

Stack Overflow用户
提问于 2013-09-18 07:05:38
回答 2查看 1K关注 0票数 4

我最近开始读“编程Ruby1.9&2.0”一书。它展示了显式枚举器的一个技巧。

代码语言:javascript
复制
triangular_numbers = Enumerator.new do |yielder|
number = 0
count = 1
    loop do
        number += count
        count += 1
        yielder.yield number
    end
end
5.times { print triangular_numbers.next, " " }
puts

我想知道为什么这个yielder.yield会暂时离开循环,并且返回数字的值,直到下一个枚举器对象创建。这似乎不同于通常情况下,当一个屈服在循环块内。我检查了APIdock,发现Proc.yield()的源代码与Proc.call()相同。对于枚举器类中的伊阿尔德对象,伊阿尔德重写了产程()。但是为什么yielder.yield会暂时离开循环块呢?

参考资料:APIdock产量()打电话

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-18 13:50:21

您混淆了Ruby的产额语句和枚举数::收益法和Proc的屈服法。它们可能拼写相同,但它们完全不同。

语句

收益声明没有接收者。在一个方法中,它的意思是“立即运行这个块”。如果没有附加块,则会发生错误。它并不总是给出一个论点,因为有时候你只是想运行这个块。

代码语言:javascript
复制
def foo
  yield :bar
end
foo # LocalJumpError
foo { |x| puts x } # bar

枚举者::

作为一个让步者,yield几乎总是被给予一个论点。这是因为它的意思与<<相同,即“下次有人在我身上调用next时,给他们这个值”。

代码语言:javascript
复制
Enumerator.new { |yielder| yielder.yield 3 }.next # 3
Enumerator.new { |yielder| yielder << 3 }.next # same thing

我认为使用<<来避免与收益语句混淆是个好主意。

流程

Procs和lambdas基本上是功能。yield在这里的意思与call相同,后者“只需调用函数”。您可以为它提供一个参数,这取决于proc是如何定义的。这里没什么花哨的。

代码语言:javascript
复制
proc { |x| puts x }.yield(:bar) # bar
proc { |x| puts x }.call(:bar) # same thing as previous line

我认为使用call来避免与收益语句混淆是个好主意。

票数 9
EN

Stack Overflow用户

发布于 2014-06-13 05:35:59

我在书中也偶然发现了这个例子。在思考了示例如何工作和浏览Ruby之后,我找到了纤维类,我认为它是场景后面的枚举器所使用的:

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

光纤概念实现了“轻量级协作并发”,这是非常有趣的,并不是很难理解,更重要的是,它不同于其他调用块或处理线程控件的“产量”。

我认为枚举器有一个光纤对象,它在其中传递给块。然后看起来就像每次在枚举数上调用" next“时,它都会调用纤对象上的”恢复“以允许它计算下一个数字,而当块调用光纤上的”产生“时,该控件返回到"next”方法。诸若此类。

下面是我可能实现枚举器的版本(当然,只有在本书示例中讨论的部分):

代码语言:javascript
复制
class MyExplicitEnumerator

  def initialize (&block)
    @yielder = Fiber.new { block.call Fiber }
  end

  def next
    @yielder.resume
  end

end

e = MyExplicitEnumerator.new do |yielder| 
    number = 1
    loop do
      yielder.yield number
      number += 1
    end
  end

p e.next
p e.next

# output
# 1
# 2
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18865860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档