Ruby与计算机科学相关的良率特征
我最近发现了Ruby的块和屈服的function,我想知道:这在计算机科学理论方面适合什么? 这是一个函数式编程技术,还是更具体的东西?
Ruby的yield
不像C#和Python那样是一个迭代器。 一旦你了解了Ruby中的块如何工作, yield
本身实际上是一个非常简单的概念。
是的,块是一个函数式编程function,即使Ruby不是一个function正常的语言。 实际上,Ruby使用lambda
方法来创build块对象,这是从Lisp的语法中借用来创build匿名函数的 – 这就是块。 从计算机科学的angular度来看,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将块包装在一个对象中,并将其作为parameter passing。 第一个是更有效率和可读性,但实际上是相同的。 你会打电话给任何一个这样的:
with_log do a = 5 other_num = gets.to_i @my_var = a + other_num end
它会打印出分配给@my_var
。 (好吧,这是一个完全愚蠢的function,但我认为你明白了。)
块在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指出的那样,它也常用于打开文件和其他许多地方。 基本上任何时候你有一个标准的function,可以使用一些自定义的逻辑(如sorting数组或处理文件),你会使用一个块。 还有其他用途,但这个答案已经这么久了,恐怕会造成体质较差的读者心脏病发作。 希望这个清除了这个话题的混乱。
产量和块比单纯循环还要多。
Enumerating enumerable系列具有一系列枚举的function,比如询问一个组中的任何一个成员的语句是否为真,或者是否所有成员都是真的,或者search满足某个条件的任何或所有成员。
块对于可变范围也是有用的。 而不仅仅是方便,它可以帮助良好的devise。 例如,代码
File.open("filename", "w") do |f| f.puts "text" end
确保文件stream在完成时即被closures,即使发生exception,并且一旦完成,variables就超出了范围。
一个休闲的谷歌没有拿出一个好的博客文章关于ruby块和产量。 我不知道为什么。
回应评论 :
我怀疑它因为块结束而closures,而不是因为variables超出了范围。
我的理解是,当指向一个对象的最后一个variables超出范围时,除了该对象有资格进行垃圾回收之外,没有什么特别的事情发生。 不过,我不知道如何确认。
我可以显示文件对象在被垃圾收集之前被closures,这通常不会立即发生。 在以下示例中,您可以看到第二个puts
语句中的文件对象已closures,但尚未被垃圾收集。
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的angular色是不是也是以CLU的名字命名的。