Interacting Objects
Learn how objects can interact with each other by defining appropriate class methods .
We'll cover the following
Objects that interact
We’re now able to create our own objects. However, they don’t do a whole lot yet. Why not create two people, and let them greet each other?
Here’s what we’d like to achieve:
class Persondef initialize(name)@name = nameenddef name@nameendendperson = Person.new("Anja")friend = Person.new("Carla")person.greet(friend)
If we run the code above, we get an error message that tells us that the greet
method needs to be defined.
To begin, we’d like this method to print out the following:
Hi Carla!
If we run the code above, we’ll get an error message that tells us what to do next:
NoMethodError: undefined method `greet' for #<Person:0x007fbb5e9c88c8 @name="Anja">
We need to define a greet
method. Let’s do that:
class Person# methods from above ...def initialize(name)@name = nameenddef name@nameend#Now,def greetendendperson = Person.new("Anja")friend = Person.new("Carla")person.greet(friend)
If we run this code, we’ll now get a different error message. That’s progress:
ArgumentError: wrong number of arguments (1 for 0)
In line 19, where the greet
method is being called, it’s taking an argument. But we never defined this method to take an argument!
How would one person greet another without knowing who that other person is? We need to make our method accept an argument:
class Person# methods from above ...def initialize(name)@name = nameenddef name@nameend#Now,def greet(other)endendperson = Person.new("Anja")friend = Person.new("Carla")person.greet(friend)
If we run this, we won’t see an error message anymore. However, it also doesn’t print anything. Our method doesn’t do anything yet.
All right, let’s add some actual behavior and print out “Hi!”
for starters.
class Person# methods from above ...def initialize(name)@name = nameenddef name@nameend#Nowdef greet(other)puts "Hi!"endendperson = Person.new("Anja")friend = Person.new("Carla")person.greet(friend)
This should output Hi!
to the screen.
However, how can Anja greet Carla specifically by using her name?
class Person# methods from above ...def greet(other)puts "Hi " + other.name + "!"endend
Let’s have another look at the full code:
class Persondef initialize(name)@name = nameenddef name@nameenddef greet(other)puts "Hi " + other.name + "!"endendperson = Person.new("Anja")friend = Person.new("Carla")person.greet(friend)
Explanation
-
We instantiate two
Person
objects and assign them two variables,person
andfriend
. We then call thegreet
method on the first one (Anja), and pass the second one (friend
, which is Carla) as an argument. -
Ruby jumps into the body of the
greet
method and assigns thePerson
instance passed (Carla) to the local variable,other
. -
It then asks the
Person
instance,other
, for their name. As a result, the"Carla"
string returns and concatenates with two other strings,"Hi "
and"!"
. This results in a new string,Hi Carla!
, which is then passed toputs
.
Let’s complicate this and let Anja add her own name to this string too:
class Persondef initialize(name)@name = nameenddef name@nameenddef greet(other)puts "Hi " + other.name + "! My name is " + name + "."endendperson = Person.new("Anja")friend = Person.new("Carla")person.greet(friend)
This now outputs:
Hi Carla! My name is Anja.
Remember how we called the add_one
method from another add_two
method before. The same works here too. We can call the person’s own method name by using it because this method is defined in the same class, and therefore can be called for every instance of Person
.
For now, let’s add another line at the end and let Carla greet Anja back. Again, here’s the full code:
class Persondef initialize(name)@name = nameenddef name@nameenddef greet(other)puts "Hi " + other.name + "! My name is " + name + "."endendperson = Person.new("Anja")friend = Person.new("Carla")person.greet(friend)friend.greet(person)
This outputs:
Hi Carla! My name is Anja.
Hi Anja! My name is Carla.
Of course, this is still quite a simplistic example. It does show, however, how we can model a certain real-world concept in terms of Ruby code, instantiate it, and let it interact with another thing.
We could have made the greet
method look prettier and a little bit easier to read by using the idea of string interpolation discussed earlier, though.