Messages are sent in Ruby anytime a method is called on an object. Messages tell objects when methods should be executed, but are not responsible for defining the behavior of the method. In the following expression, “cool”.upcase, the upcase message is sent to the “cool” object to instruct the “cool” object to invoke the upcase method, which is defined in the String class. A message is simply an instruction for an object to invoke a method. Let’s decompose this example into its components:
“cool” – is the recipient of the message and is called the “message receiver”. Once the “cool” object receive the message, it tries to find where the method is defined and execute the method.
The dot operator is used to separate the message receiver (“cool”) from the message (upcase).
The upcase message is sent to the receiver and the message receiver always assumes that the name of the message is the same as the name of the method that should be executed.
The send method can also be used to send messages to an object.
The send method uses a different syntax than dot notation, but the semantics are the same. In this example, the upcase message is sent to the receiver (i.e. the “cool” object) and the receiver responds by looking up a method with the same name as the message and invoking the appropriate code.
Methods with parameters accept messages with arguments. Let’s add a singleton method called add to the “cool” object:
c = "cool" def c.add(x, y) x + y end
The add method requires two arguments, so the message must include the required arguments to successfully invoke the method. Arguments can be passed in a message using either dot notation or the send method.
>> c.add(1, 4) => 5 >> c.send(:add, 5, 6) => 11
If the required arguments are not provided in the message, an ArgumentError exception will be raised.
>> c.send(:add) => ArgumentError