Ruby中的块是什么意思?它看起来与Smalltalk类似,但您无法向其发送消息。
例如,在smalltalk中:
[:x | x + 3] value: 3
返回6.但是在红宝石中:
{|x| x + 3}.call 3
将导致SyntaxError。
好吧,你可以将消息传递给ruby中的lambda,但是:
irb(main):025:0> ->(x){x+3}.call 3
=> 6
所以在Ruby中,块不是一个块,但lambda是一个块?这是真的?我的意思是,ruby lambda和smalltalk块之间有什么区别吗?如果这是真的,那么什么是红宝石块呢?
更新:
从下面的评论和答案,以及一些谷歌搜索,我想我
对Ruby块有更多的了解。在Ruby中,通常一段代码会计算一个值,而每个值都是一个对象。但是,块不会评估值。所以这不是一个对象。相反,它可以充当 部分 一个对象。例如,在{| x | x + 3}可以作为对象proc {| x |的一部分x + 3}。
但它确实让我困惑。在smalltalk中,几乎每个表达式都可以分为对象(绑定到变量是例外)。在Ruby中似乎有更多例外。
首先,Ruby块不是最重要的东西:一个对象。它是一个语法结构,显然也有一个等效的实现 - 但它不是一个对象,因此不能接收消息。这就是你的榜样
{|x| x + 3}.call 3
不合语法。 Lambdas,procs - 那些是包裹块的对象,并且有一个 call
执行块的方法。
因此,块只是一段代码,可以传递给参数列表之外的方法 - 不多也不少。例如,如果将它传递给Proc.new构造函数,它将包装它并为您提供一个可以处理的对象:
Proc.new {|x| x + 3}.call 3
精度:
我甚至会说,在smalltalk中甚至绑定都是用对象组成的。
想想MethodContext。
你实际做的是将对象存储在MethodContext中。
所以
a := Object new
可以重写:
thisContext at: 1 put: Object new.
但显然你不会这样写,因为你需要知道temps是变量。
Smalltalk中的一个块 是一个匿名对象。从语法上讲,它由a分隔 [
... ]
对。
在评估时,它将返回在其自身内评估的最后一个表达式,并且其协议中有许多方法。
以下是来自Smalltalk的块的类注释(在本例中,Dolphin Smalltalk 6.03社区版)
“块封装了一系列语句,以便稍后执行。块可以从创建它们的封闭词法范围中捕获(或”关闭“)运行时状态,例如临时变量的值。对块进行求值,就好像它在定义它的词法作用域中一样,除了块可能具有在评估时绑定的参数。块可以作为参数传递给消息到其他对象,并在适当的时候由这些对象进行评估,因此形成了一个非常强大和通用的“可插拔”机制,这是一个核心功能,它提供了Smalltalk的大部分功能。
相比之下, Ruby中的一个块 只是一个参数字符串。它在语法上由a分隔 {
... }
对,但它没有自己的方法。