Message Sending Expression
In this chapter, we will identify the sender, receiver, message and arguments in a message sending expression.
By now, you already know:
- There is always a receiver.
- There is always a sender.
- There is always a message that passes between the sender and the receiver.
Let's see an example that ties all these concepts together.
Let's write the simplest program to illustrate the three key takeaways of this book so far.
x = 1 + 2 p x
This prints 3.
The above program can be rewritten in an equal way.
x = 1.+ 2 p x
This also prints 3. This example makes sending a message explicit by using the dot notation.
The above program can be rewritten in an another way.
x = 1.+(2) p x
This also prints 3. This example makes the argument, 2 to the message + explicit.
It's now clear that 1 is the receiver. We already know that this object is Fixnum.
The sender is implicit because we have written this code at the top level context. We know that main object is the sender.
Sending a Message
The + is not an operator in Ruby. The + is a message that passes between the sender and the receiver. Let's verify it.
The respond_to? method takes a symbol of the method name as the argument and returns either true or false depending on whether it can respond to it or not. This prints:
This proves that Fixnum object responds to the + message. We can explicitly send the message to Fixnum object.
p 1.send(:+, 2)
The send method is defined in Kernel module and is mixed into the Object. So, it's available everywhere. The first argument to the send method is the symbol of the method name and the second argument is the argument for that method. This prints 3.
Convert Message to an Object
We can convert the + message sent to the Fixnum object into an object and call it.
> addition = 1.method(:+) => #<Method: Fixnum#+> > addition.call(2)
The method called method is defined in Kernel module. Since the Kernel module is mixed into the Object, it's available everywhere. This returns a Method object. We send the call message with 2 as the argument to add 1 and 2. This prints 3.
Are there other messages in Ruby that looks like an operator?
Yes, you can experiment in the IRB and get a list of those messages:
> 1.public_methods(false) => [:%, :&, :*, :+, :-, :/, :<, :>, :^, :|, :~, :-@, :**, :<=>, :<<, :>>, :<=, :>=, :==, :===, :,...]
The false argument is used to list only the methods found in Fixnum class. We can also send the instance_methods message to the Fixnum class.
[:-@, :+, :-, :*, :/, :%, :**, :==, :===, :<=>, :>, :>=, :<, :<=, :~, :&, :|, :^, :, :<<, :>>, ...]
You must read 1 + 2 as, the object 1 is sent the message +, with the object 2 as the argument.
In this chapter, you learned that in Ruby, adding two numbers is a first-class message sending expression. We identified the sender, receiver, message and the argument in the message sending expression.