Ruby 中的 Block 与 Smalltalk 的比较

发布于 2024-09-04 15:10:16 字数 691 浏览 9 评论 0原文

Ruby 中的阻塞是什么意思?它看起来与 Smalltalk 类似,但你不能向它发送消息。

例如,在smalltalk中:

[:x | x + 3] value: 3

返回6。但在ruby中:

{|x| x + 3}.call 3

会导致SyntaxError。

好吧,你可以在 ruby​​ 中将消息传递给 lambda:

irb(main):025:0> ->(x){x+3}.call 3
=> 6

那么在 Ruby 中,block 不是一个块,但是 lambda 是一个块?这是真的吗?我的意思是,ruby lambda 和smalltalk 块之间有什么区别吗?如果这是真的,那么红宝石块是什么?

更新:

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

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

What does block in Ruby mean? It looks similar with Smalltalk, but you can't send messages to it.

For example, in smalltalk:

[:x | x + 3] value: 3

returns 6. But in ruby:

{|x| x + 3}.call 3

will cause SyntaxError.

Well, you can pass messages to lambda in ruby, though:

irb(main):025:0> ->(x){x+3}.call 3
=> 6

So in Ruby, block is not a block, but lambda is a block? Is this true? I mean, are there any differences between ruby lambda and smalltalk block? If this is true, then what is a ruby block?

Update:

From the comment and answer below, together with some googling, I guess I
have more understanding of Ruby block. In Ruby, usually a piece of code evaluates an value, and every value is an object. But, block doesn't evaluate an value. So it's not an object. Instead it can act as part of an object. For example, in {|x| x + 3} can act as a part of the object proc {|x| x + 3 }.

But it did confuse me. In smalltalk, almost every expression can be divided into objects (binding to variables are exceptions). It seems in Ruby, there are more exceptions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谁把谁当真 2024-09-11 15:10:16

首先,也是最重要的一点,Ruby 块不是一个对象。它是一个语法构造,并且显然也有一个等效的实现 - 但它不是一个对象,因此无法接收消息。这使得你的例子

{|x| x + 3}.call 3

不符合语法。 Lambda、procs - 这些是包装块的对象,并且具有执行该块的 call 方法。

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

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

First and the most important thing that Ruby block isn't: an object. It is a syntactic construct, and also obviously has an equivalent implementation - but it is not an object, and thus can't receive messages. Which makes your example of

{|x| x + 3}.call 3

ungrammatical. Lambdas, procs - those are objects that wrap a block, and have a call method which executes the block.

Thus, a block is simply a piece of code which can be passed to a method, outside the argument list - no more, no less. If you pass it to Proc.new constructor, for example, it will wrap it and give you an object you can handle:

Proc.new {|x| x + 3}.call 3
烟若柳尘 2024-09-11 15:10:16

准确地说:

我什至会说,在smalltalk中,即使绑定也是由对象组成的。
想想 MethodContext。
您实际上所做的是将对象存储在 MethodContext 中。
所以

a := Object new

可以重写为:

thisContext at: 1 put: Object new.

但显然你不会这样写,因为你需要知道 temps 变量是多少。

A precision:

I would even say that in smalltalk even binding is made up with object.
Think of the MethodContext.
What you are actually doing is to store the object in the MethodContext.
So

a := Object new

Can be rewrite in:

thisContext at: 1 put: Object new.

But obviously you wont write it this way since you need to know were are the temps variable.

白云不回头 2024-09-11 15:10:16

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

当计算时,它将返回其内部计算的最后一个表达式,并且其协议中有很多方法。

以下是来自 Smalltalk 的 Blocks 的类注释(在本例中为 Dolphin Smalltalk 6.03 Community Edition)

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

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

A block in Smalltalk is an anonymous object. Syntactically, it is delimited by a [ ... ] pair.

When evaluated, it will return the last expression evaluated within itself, and there are lots of methods in its protocol.

Here are the Class comments for Blocks from a Smalltalk (in this instance, Dolphin Smalltalk 6.03 Community Edition)

"Blocks encapsulate a sequence of statements to be performed at a later time. Blocks may capture (or "close over") runtime state, such as the values of temporary variables, from the enclosing lexical scope at the point where they are created. When evaluated a block executes as if in the lexical scope in which it was defined, except that blocks may have arguments that are bound at the time of evaluation. Blocks may be passed as arguments with messages to other objects and evaluated by those objects when appropriate, and thus form a very powerful and generic "pluggability" mechanism that is a core feature which provides much of the power of Smalltalk".

By contrast, a block in Ruby is simply a parameter string. It's syntactically delimited by a { ... } pair, but it has no methods of its own.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文