PHP’s built in Type Hinting feature is completely optional. You can craft entire applications without ever type hinting once. However, if you don’t you’re missing out on a great way to ensure arguments to methods adhere to an interface.

By implementing an Interface on a Class, you’re guaranteeing that the Class implements the entirety of the Interface’s signature a.k.a. it’s public methods.

Let’s reuse our simple interface from the last section:

  interface Animal {
    
    /**
     * Every animal has to eat, right?
     */
    public function eat();
  }

Now we’re going to guarantee this Cat can eat by implementing the Animal interface on it:

  class Cat implements Animal {
    public function eat($food) {
      echo "nom nom $food";
    }
  }

Cat implements Animal, so that means we know that a Cat can eat.

While we’re at it, let’s just let Dog’s in too:

  class Dog implements Animal {
    public function eat($food) {
      echo "bark bark $food";
    }
  }

So, that means we can open up a AnimalShelter and feed our Animals without knowing exactly what kind of Animal is at the shelter:

  class AnimalShelter {

    /**
     * @var array
     */
     private $animals;

     /**
      * Add a new animal to our little shelter
      *
      * @param Animal
      * @return void
      */
     public function addAnimal(Animal $animal) {
        $this->animals[] = $animal;
     }

     /**
      * Time to feed the animals!
      *
      * @param string
      * @return void
      */
     public function feed($food) {
        foreach($this->animals as $animal) {
          $animal->eat($food);
        }
     }
  }

Alright, so our AnimalShelter can take in any Animal implementation by adding them to an internal array through the addAnimal method.

Then we can feed them with $food. The Animal contract guarantees that each Animal has the eat public method and we type hinted Animal in the feed method so no argument will be accepted unless it’s an animal.

Let’s see it in action:

$cat = new Cat;
$dog = new Dog;

$shelter = new AnimalShelter;

$shelter->addAnimal($cat);
$shelter->addAnimal($dog);

$shelter->feed('bacon');

=> 'nom nom bacon'
=> 'bark bark bacon'

This is a great way of making polymorphic and reusable code. The AnimalShelter doesn’t really care what kind of Animal comes through it’s doors. If one day we need to support Alligator’s coming in, we don’t have to update the AnimalShelter’s code at all.

Type Hinting in Ruby

Ok, this title is totally misleading. There is no type hinting in Ruby whatsoever. In PHP we have the ability to type hint both incoming parameters and returned parameters from functions.

Is polymorphic code possible in Ruby then? Absolutely.

Interfaces jobs are to ensure a public signature on a class. How can we do that in Ruby? One answer isn’t all that complicated, it’s Guard Statements:


class Cat
  def eat(food)
    puts "nom nom #{food}"
  end
end

class Dog
  def eat(food)
    puts "bark bark #{food}"
  end
end

Now Cat and Dog share the same signature. Now let’s create an AnimalShelter that can house and feed them:


class AnimalShelter

  def addAnimal(animal)
    raise ArgumentError('Given animal doesn\'t implement .eat!') unless animal.method_defined?(:eat)
    @animals << animal
  end

  def feed(food)
    @animals.each do |animal|
      animal.eat(food)
    end
  end
end

In our addAnimal method, we raise an ArgumentError unless the given animal can eat.

This is the logical equivalent of implementing an interface, but it’s actually easier to read. It’s an example of defensive programming, where you’re checking for the incoming data before processing it.

Now I wish Ruby had type hinting & interfaces built into the language. There’s something about the comfort of knowing a particular is absolutely defined on an incoming argument. However, this is how the language is written.

I don’t see the Guard Statement being any less readable than an interface. Just like PHP, these types of Guard Statments are totally optional.