Reputation: 1127
I've seen code like this:
def some_method
# ...
end.another_method
What does the end.another_method
part do?
Upvotes: 7
Views: 2750
Reputation: 369536
In Ruby, the .
is the message sending operator. (In other languages, it would be called a method calling operator instead.) So, when you say
foo.bar
it means "evaluate foo
and send the message bar
to the result of evaluating foo
".
In this particular case, you are sending the message another_method
to the result of evaluating
def some_method; end
The Ruby Language Specification says that the value of a method definition expression is undefined and should be ignored; and on most Ruby implementations, method definition expressions simply evaluate to nil
, which isn't terribly useful.
However, on some implementations, method definition expressions do evaluate to something more useful than nil
. On Rubinius, for example, they evaluate to the CompiledMethod
object for the method being defined. And CompiledMethod
has a rich API, so sending messages to a CompiledMethod
object definitely makes sense.
It has also been proposed that method definition expressions should return a Symbol
corresponding to the name of the method being defined or a Method
object.
Put simply: the dot in this particular case means the exact same thing it always means in Ruby: send a message, call a method, invoke a member function, whatever you want to call it.
Upvotes: 8
Reputation: 44090
I believe that your example is wrong, as what you are doing here is defining a method and calling a method on the result of a method definition (not a method call), which is always (usually?) nil
.
There's a similar form which fmendez is referring to, but end
is the end of a block, not a method definition in that case.
So, for example:
array.map do |element|
element * element
end.sum
would, hypothetically, return a sum of squares of elements of given array.
But, if you are doing method chaining like this, it is more common to use bracket style blocks instead of do..end
, so the above example would read:
array.map{ |element|
element * element
}.sum
Blocks in Ruby are method arguments, not unlike any other method arguments (apart from the dedicated syntax), so putting dot after end
is not different than putting the dot after )
in
'hello'.concat(' world!').capitalize
Which is also an example of method chaining.
Upvotes: 11