Interacting Objects

We’re now able to create our own objects. However, they don’t do a whole lot, yet, right? Why not create two people, and let them greet each other.

Let’s see.

Here’s what we’d like to achieve:

class Person
  def initialize(name)
    @name = name
  end

  def name
    @name
  end
end

person = Person.new("Anja")
friend = Person.new("Carla")

person.greet(friend)

We’d like this to print out the following for starters:

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">

Right, we need to define a method greet. Let’s do that:

class Person
  # methods from above ...

  def greet
  end
end

If we run this code, we’ll now get a new error message. Great, that’s progress:

ArgumentError: wrong number of arguments (1 for 0)

Right, how would one person greet another without knowing who that other person is? So we need to make our method accept an argument:

class Person
  # methods from above ...

  def greet(other)
  end
end

If we run this we won’t see an error message any more. Yay! However, it also does not print anything so far - our method does not do anything, yet.

Alright, let’s add some actual behaviour, and print out “Hi!” for starters.

class Person
  # methods from above ...

  def greet(other)
    puts "Hi!"
  end
end

What happens when you run that? It works, right. This should output Hi! to the screen.

However, how can Anja greet Carla, specifically? How can any person greet any other person? Well, the method knows the person to greet (she has been passed as an argument to the method) so she can ask her for her name:

class Person
  # methods from above ...

  def greet(other)
    puts "Hi " + other.name + "!"
  end
end

Does this make sense?

Let’s have another look at the full code:

class Person
  def initialize(name)
    @name = name
  end

  def name
    @name
  end

  def greet(other)
    puts "Hi " + other.name + "!"
  end
end

person = Person.new("Anja")
friend = Person.new("Carla")

person.greet(friend)

So we instantiate two Person objects, and assign them two variables person and friend. Then we call the method greet on the first one (Anja), and pass the second one (friend, which is Carla) as an argument.

Now Ruby jumps into the method body of the method greet, and assigns the local variable name other to the Person instance passed (i.e. Carla).

It then asks the Person instance other for their name (which will return the String "Carla", and concatenates it to (glues it together with) two other strings "Hi " and "!". So this results in a new String Hi Carla! which it then passes to puts.

Ok, let’s spice that up a little, and let Anja add her own name to this String, too:

class Person
  # methods from above ...

  def greet(other)
    puts "Hi " + other.name + "! My name is " + name + "."
  end
end

Nice. This now outputs:

Hi Carla! My name is Anja.

Remember how you could call the method add_one from another method add_two before? The same works here, too: We can call the person’s own method name by just using it, since this method is defined on the same class, and thus every instance of Person. We’ll look at this a little more in the next chapter.

For now let’s add another line at the end, and let Carla greet Anja back.

Again, here’s the full code:

class Person
  def initialize(name)
    @name = name
  end

  def name
    @name
  end

  def greet(other)
    puts "Hi " + other.name + "! My name is " + name + "."
  end
end

person = Person.new("Anja")
friend = Person.new("Carla")

person.greet(friend)
friend.greet(person)

And this outputs:

Hi Carla! My name is Anja.
Hi Anja! My name is Carla.

What do you think?

Of course this is still quite a simplistic example. It already shows how you can “model” a certain “real-world” concept in terms of Ruby code, instantiate it, and let it interact with another thing.

By the way if you’d like to see how to make the method greet more pretty, and a little bit easier to read, check out the chapter on String interpolation.