Block in Ruby compared to Smalltalk
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 开发者_StackOverflow社区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.
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
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.
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.
精彩评论