Ruby 中的 Block 与 Smalltalk 的比较
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,也是最重要的一点,Ruby 块不是一个对象。它是一个语法构造,并且显然也有一个等效的实现 - 但它不是一个对象,因此无法接收消息。这使得你的例子
不符合语法。 Lambda、procs - 这些是包装块的对象,并且具有执行该块的
call
方法。因此,块只是一段可以传递给参数列表之外的方法的代码 - 不多也不少。例如,如果将其传递给 Proc.new 构造函数,它将包装它并为您提供一个可以处理的对象:
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
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:
准确地说:
我什至会说,在smalltalk中,即使绑定也是由对象组成的。
想想 MethodContext。
您实际上所做的是将对象存储在 MethodContext 中。
所以
可以重写为:
但显然你不会这样写,因为你需要知道 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
Can be rewrite in:
But obviously you wont write it this way since you need to know were are the temps variable.
Smalltalk 中的块是一个匿名对象。从语法上讲,它由
[
...]
对分隔。当计算时,它将返回其内部计算的最后一个表达式,并且其协议中有很多方法。
以下是来自 Smalltalk 的 Blocks 的类注释(在本例中为 Dolphin Smalltalk 6.03 Community Edition)
相比之下,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)
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.