Ruby中的Block与Smalltalk相比

时间:2010-06-06 10:42:54

标签: ruby smalltalk

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中,block不是块,但lambda是块?这是真的?我的意思是,红宝石lambda和smalltalk块之间有什么区别吗?如果这是真的,那么什么是红宝石块?

更新:

从下面的评论和答案,以及一些谷歌搜索,我想我 对Ruby块有更多的了解。在Ruby中,通常一段代码会计算一个值,而每个值都是一个对象。但是,块不会评估值。所以这不是一个对象。相反,它可以充当对象的部分。例如,在{| x |中x + 3}可以作为对象proc {| x |的一部分x + 3}。

但它确实让我困惑。在smalltalk中,几乎每个表达式都可以分为对象(绑定到变量是例外)。在Ruby看来,还有更多例外。

3 个答案:

答案 0 :(得分:14)

首先,Ruby块不是最重要的东西:一个对象。它是一个语法结构,显然也有一个等效的实现 - 但它不是一个对象,因此无法接收消息。这是

的例子
{|x| x + 3}.call 3

不合语法。 Lambdas,procs - 那些是包装块的对象,并且有一个call方法来执行块。

因此,一个块只是一段代码,可以传递给参数列表之外的方法 - 不多也不少。例如,如果将它传递给Proc.new构造函数,它将包装它并为您提供一个可以处理的对象:

Proc.new {|x| x + 3}.call 3

答案 1 :(得分:1)

精度:

我甚至会说,在smalltalk中甚至绑定都是由对象组成的。 想想MethodContext。 你实际做的是将对象存储在MethodContext中。 所以

a := Object new

可以改写:

thisContext at: 1 put: Object new.

但显然你不会这样写,因为你需要知道临时变量。

答案 2 :(得分:1)

Smalltalk中的一个块是一个匿名对象。从语法上讲,它由[ ... ]对分隔。

评估时,它将返回自身内部评估的最后一个表达式,并且其协议中有许多方法。

以下是Smalltalk中块的类注释(在本例中为Dolphin Smalltalk 6.03社区版)

  

“Blocks”封装了一系列将在稍后执行的语句。块可以捕获(或“关闭”)运行时状态,例如临时变量的值,来自封闭的词法范围。当被评估时,块执行就像在定义它的词法范围中一样,除了块可能具有在评估时绑定的参数。块可以作为参数传递给消息到其他对象并由这些对象评估在适当的时候,形成一个非常强大和通用的“可插拔”机制,这是一个核心功能,提供Smalltalk的大部分功能“。

相比之下, Ruby中的块只是一个参数字符串。它在语法上由{ ... }对分隔,但它没有自己的方法。