函数式编程-与计算机科学有关的Ruby yield特性

我最近发现了Ruby的块和屈服功能,我想知道:从计算机科学理论的角度来看,这适合什么? 它是一种功能编程技术,还是更具体的东西?

hbw asked 2020-02-05T01:23:21Z
4个解决方案
104 votes

Ruby的@my_var不是像C#和Python那样的迭代器。 一旦了解了Ruby中的块是如何工作的,那么yield本身实际上就是一个非常简单的概念。

是的,即使Ruby不是适当的功能语言,块也是一种功能编程功能。 实际上,Ruby使用方法@my_var来创建块对象,该对象是从Lisp的语法中借来的,用于创建匿名函数-这就是块。 从计算机科学的角度来看,Ruby的块(以及Lisp的lambda函数)是闭包。 在Ruby中,方法通常只占用一个块。 (您可以通过更多,但很尴尬。)

Ruby中的@my_var关键字只是一种调用已赋予方法的块的方式。 这两个示例是等效的:

def with_log
  output = yield # We're calling our block here with yield
  puts "Returned value is #{output}"
end

def with_log(&stuff_to_do) # the & tells Ruby to convert into
                           # an object without calling lambda
  output = stuff_to_do.call # We're explicitly calling the block here
  puts "Returned value is #{output}"
end

在第一种情况下,我们只是假设有一个方块并说要调用它。 另一方面,Ruby将块包装在一个对象中,并将其作为参数传递。 第一个是更有效和可读的,但实际上它们是相同的。 您可以这样称呼任何一个:

with_log do
  a = 5
  other_num = gets.to_i
  @my_var = a + other_num
end

并且它将打印最终分配给@my_var的值。(好的,所以这是一个完全愚蠢的功能,但是我想您知道了。)

块在Ruby中用于很多事情。 几乎您会在每个地方(例如Java)使用循环,在Ruby中,循环都被带有块的方法所取代。 例如,

[1,2,3].each {|value| print value} # prints "123"
[1,2,3].map {|value| 2**value}    # returns [2, 4, 8]
[1,2,3].reject {|value| value % 2 == 0} # returns [1, 3]

正如Andrew所指出的,它也常用于打开文件和许多其他地方。 基本上,只要您具有可以使用某些自定义逻辑的标准函数(例如,对数组进行排序或处理文件),就会使用一个块。 也有其他用途,但是这个答案已经很久了,我担心它会导致体质较弱的读者心脏病发作。 希望这可以消除对该主题的困惑。

Chuck answered 2020-02-05T01:24:03Z
6 votes

除了循环之外,还有更多的收益和障碍。

“枚举可枚举”系列提供了一系列可用于枚举的功能,例如询问某个语句对某个组的任何成员是否正确,或者对所有成员是否正确,或者搜索满足某个条件的任何或所有成员 。

块对于可变范围也很有用。 它不仅可以方便使用,还可以帮助您进行良好的设计。 例如,代码

File.open("filename", "w") do |f|
  f.puts "text"
end

确保在完成文件流后将其关闭,即使发生异常,并且确保变量在完成后也不会超出范围。

随便的Google都没有提出关于红宝石块和产量的好博客文章。 我不知道为什么

对评论的回应:

我怀疑它是由于块结尾而关闭的,而不是因为变量超出了范围。

我的理解是,当指向对象的最后一个变量超出范围时,除了该对象可以进行垃圾回收外,没有什么特别的事情发生。 我不知道如何确认。

我可以证明文件对象在被垃圾回收之前就已经关闭,通常不会立即发生。 在以下示例中,您可以看到在第二个puts语句中关闭了文件对象,但是该文件对象尚未被垃圾回收。

g = nil
File.open("/dev/null") do |f|
  puts f.inspect # #<File:/dev/null>
  puts f.object_id # Some number like 70233884832420
  g = f
end
puts g.inspect # #<File:/dev/null (closed)>
puts g.object_id # The exact same number as the one printed out above,
  # indicating that g points to the exact same object that f pointed to
Andrew Grimm answered 2020-02-05T01:25:00Z
2 votes

我认为yield语句起源于CLU语言。 我一直想知道Tron的角色是否也以CLU命名...

Daniel Lucraft answered 2020-02-05T01:25:20Z
0 votes

我认为“协程”是您要寻找的关键字。

例如。 [http://en.wikipedia.org/wiki/Yield]

计算和信息科学的收益:

  • 在计算机科学中,协程的返回点(和重新输入)
Brian answered 2020-02-05T01:25:53Z
translate from https://stackoverflow.com:/questions/764134/rubys-yield-feature-in-relation-to-computer-science