词语产量的含义

目前我正在阅读David A. Black的“The Well-Grounded Rubyist”,我坚持10.9章(枚举器和可枚举的下一个维度)。 我的问题是关于yield方法。 Ruby上下文中yield这个词的含义是什么? 我的母语是俄语,谷歌翻译给我看了一堆翻译变体,让我感到困惑。 其中有一些: 给予带来投降放弃 ), 生产同意遵守和许多其他人。

UPD:请注意这个事实,我试图理解Enumerator :: Yielder#yield方法的含义,但不是yield关键字本身。

UPD_2:我发现了有关枚举器的有趣文章:“ Ruby中的懒惰枚举器 ”。

单词yield在Ruby的上下文中并没有任何特殊含义。 它与其他编程语言或编程和计算机科学中的含义完全相同。

它通常在某种执行上下文放弃控制流到不同的执行上下文时使用。 例如,在Unix中,有一个sched_yield函数,线程可以使用该函数将CPU放弃到另一个线程(或进程)。 对于协同程序,术语“ yield通常用于将控制权从一个协程转移到另一个协程。 在C#中,有一个yield关键字,迭代器方法使用它来放弃对迭代方法的控制。

实际上,这最后一个用法与Ruby中的Enumerator::Yielder#yield方法的用法完全相同,您要问的是。 调用此方法将暂停枚举器并放弃对枚举方法的控制。

例:

 fibs = Enumerator.new do |y| a, b = 0, 1 y.yield a loop do y.yield b a, b = b, a + b end end puts fibs.next # 0 puts fibs.next # 1 puts fibs.next # 1 puts fibs.next # 2 puts fibs.next # 3 puts fibs.next # 5 puts fibs.next # 8 puts fibs.next # 13 puts fibs.next # 21 

如你所见,存在无限循环。 显然,如果这个循环只是单独运行,那就不会有多大用处。 但是因为每次碰到yield方法,它都会放弃控制直到再次调用它,这将逐个产生Fibonacci数,基本上代表了所有Fibonacci数的无限长列表。

还有另一种方法Fiber.yield ,它具有类似的用途。 (事实上​​,我已在上面对其进行了描述,因为Fiber只是Ruby的协同程序名称。)在Fiber ,您可以调用Fiber.yield来放弃对最初控制给您的执行上下文的控制。

最后,有一个yield关键字,它在方法体内部用于放弃对传递给方法的块的控制。

请注意,至少在Enumerator情况下(即第一个示例),您还可以将yield解释为生成 ,因为Enumerator每次调用yield都会生成一个新值。

在枚举器中屈服的背景下,意义最接近于“带来”。 Enumerator调用其yielder对象的yield方法,该方法“带出”传递给它的任何值。

 give_me = Enumerator.new do |yielder| (1..5).each do |n| yielder.yield n end end 5.times do p give_me.next end 

这导致:
1
2
3
4

在屈服于一个区块的情况下,意义最接近于“投降”。 带有yield语句的方法将执行放弃到传递给该方法的任何块。

 def wage_war p "What should I do?" yield end wage_war { p "Surrender!" } 

@Prostosuper,我最喜欢的相关定义就是这个 :

让步,放弃,给予(放弃;放弃或放弃对他人的物理控制)

在@Jamie Forrest的例子中,当调用wage_war时,“我该怎么办?” 首先打印,然后将流量控制产生 (承认,割让,授予,给予)给pay_war被调用的块,导致“投降!” 正在印刷。 该块完成后,流量控制将在wage_war中恢复。 如果在收益率之后还有另一个语句,那么在“投降”之后,当在wage_war中恢复流量控制时,它将被执行。 被打印了。

编辑 :@Prostosuper问及与枚举器有关的屈服,而不是块,我的例子讨论了它在块中的使用。 关于Enumerator :: Yielder#yield的SO问题(有答案)就在这里 。 定义的意义仍然适用。

您可能会发现阅读Programming Ruby 1.9对yield关键字所说的内容很有趣:

编程语言增益程序很高兴知道选择关键字yield是为了回应Liskov语言CLU中的yield函数,这种语言已有三十多年的历史,但仍包含尚未被CLU广泛利用的特性 -减。

更多阅读:

CLU的历史 (pdf)

芭芭拉·利斯科夫 (维基百科)

yield,在ruby上下文中“带来”:)作为参数传递给您的方法的块。

 def my_method p "I have to say something:" yield end my_method do p "hello world!" end 

版画

 I have to say something: hello world 

当my_method达到yield时,执行代码p“hello world”