Message Passing
In this chapter, you will learn the basics of message passing. We will discuss about message sender and the difference between intent and implementation. We will also see an example for an explicit sender.
Explicit and Implicit Sender
This chapter will examine a program with an explicit sender. In a later chapter we will revisit our hail taxi program to identify an implicit sender.
Sender Sends a Message to a Receiver
In Ruby, the message-sending metaphor is the basis for object interaction.
Why is message-sending metaphor used? Because it provides modularity.
The metaphor decouples the intent of a message from the implementation details of the method. This allows us to vary the implementation without impacting the objects that send the messages.
Intent vs Implementation
The messages are more important than the objects involved in the interaction. We express intent by means of the messages we send. The name of the message embodies the intent of a message. The implementation details are hidden behind the method. In this example, the intent is to say hello. The implementation is using either a string telephone or a rotary telephone.
Responding to Messages
In statically typed languages, you know at compile time the set of messages an object can handle. In Ruby, the objects can gain the ability to respond to new messages at run-time. It can also lose the ability to respond to messages at run-time.
Collaborating Objects
In the book, Object-Oriented Programming and Java by Poo, Danny, Kiong et al, the authors say:
Objects communicate with one another by sending messages. A message is a method call from a message-sending object to a message-receiving object. A message-sending object is a sender while a message-receiving object is a receiver.
Sender Object
The sender is the object that owns the scope where the message originates.
Explicit Sender
Let's now look at an example where the sender is explicit in the code.
class Teacher
def initialize(student)
@student = student
end
def ask_student_name
@student.tell_name
end
end
class Student
def initialize(name)
@name = name
end
def tell_name
@name
end
end
student = Student.new('Bugs Bunny')
teacher = Teacher.new(student)
p teacher.ask_student_name
This prints:
Bugs Bunny
We create an instance of a Student class with the name Bugs Bunny. We then create an instance of a Teacher class and pass in the student object to its constructor. We send ask_student_name message to the teacher object that plays the role of a receiver.
Then the ask_student_name method runs. Inside this method, we can print the value of the sender object.
def ask_student_name
p "The sender object is : #{self}"
@student.tell_name
end
This prints:
The sender object is : #<Teacher:0x007fc3b40>
Bugs Bunny
We can make this concept explicit by printing the name of the class.
def ask_student_name
puts "The sender object is : #{self.class}"
@student.tell_name
end
This prints:
The sender object is : Teacher
Bugs Bunny
Fabio Asks
How did you figure out what and where to print the value of the sender object?
Ask yourself the following questions.
- Where did the message originate?
- Which object owns the scope at that instant?
The answer for the question one, the line:
@student.tell_name
The answer for the question two, the value of self owns the scope at that instant.
- Every sender and receiver in a message passing interaction is an object.
- Sender can be either explicit or implicit.
- Sender is the owner of the scope where the message originates.
Summary
In this chapter, you learned the basics of message passing. You learned about the message sender and the difference between intent and implementation. We also saw an example for an explicit sender.