我最近发现了 Ruby 的块和产生特性,我想知道:这在计算机科学理论方面适合什么?它是一种函数式编程技术,还是更具体的东西?
4 回答
Rubyyield
不像 C# 和 Python 那样是迭代器。yield
一旦您了解了块在 Ruby 中的工作原理,它本身实际上是一个非常简单的概念。
是的,块是一种函数式编程特性,尽管 Ruby 并不是一种适当的函数式语言。事实上,Ruby 使用该方法lambda
来创建块对象,这是从 Lisp 用于创建匿名函数的语法中借用的——这就是块的含义。从计算机科学的角度来看,Ruby 的块(和 Lisp 的 lambda 函数)是闭包。在 Ruby 中,方法通常只占用一个块。(你可以通过更多,但这很尴尬。)
Ruby 中的yield
关键字只是一种调用已赋予方法的块的方式。这两个例子是等价的:
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 所指出的,它也常用于打开文件和许多其他地方。基本上只要你有一个可以使用一些自定义逻辑的标准函数(比如排序数组或处理文件),你就会使用一个块。还有其他用处,不过这个答案已经这么长了,恐怕会导致体质较弱的读者心脏病发作。希望这可以消除对该主题的困惑。
除了循环之外,还有更多的收益和阻塞。
Enumerating enumerable系列有一系列你可以用枚举做的事情,比如询问一个陈述是否对一个组的任何成员都为真,或者它是否对所有成员都为真,或者搜索任何或所有满足特定条件的成员.
块对于变量范围也很有用。它不仅方便,还可以帮助进行良好的设计。例如,代码
File.open("filename", "w") do |f|
f.puts "text"
end
确保文件流在您完成后关闭,即使发生异常,并且一旦您完成该变量就超出范围。
一个随便的谷歌没有想出一篇关于红宝石块和产量的好博客文章。我不知道为什么。
回复评论:
我怀疑它是因为块结束而关闭的,而不是因为变量超出范围。
我的理解是,当指向对象的最后一个变量超出范围时,除了该对象有资格进行垃圾收集外,没有什么特别的事情发生。不过,我不知道如何确认这一点。
我可以证明文件对象在被垃圾收集之前就被关闭了,这通常不会立即发生。在下面的示例中,您可以看到在第二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
我认为该yield
语句起源于CLU语言。我一直想知道Tron的角色是否也以CLU命名......