Taking a Quack at Duck Typing

Your friend, Ruby, goes out and buys¬†Java a pet duck. But wait, on closer inspection, it’s not a duck at all! It just walks like a duck.

Quack!

And quacks like a duck.

“What’s the matter?” Ruby asks.

“It’s not a duck!” Java complains, distraught that the pet has no inheritance relations with the Duck class.

“If it walks like a duck, and quacks like a duck, it’s a duck!”

So what is duck typing?


Duck typing is a feature that allows a language to call a method on an object, if it has the method. Ruby doesn’t care what the object is, but rather, what methods the object has.

However, a caveat of duck typing is that the it tends to only be built-in to the language if the language handles type checking during runtime. This means that duck typing will only work on dynamically typed languages, such as Ruby. In languages like Java and C++, type checking is done during compile-time. As a result, if there is a type conflict, the program will not even compile. Languages that do type-checking during compile-time are called statically typed languages.

In Java, declaring an integer will look like this :

int x = 0;

The type (int) is explicitly stated, which means that Java checks for types during compile-time, making it a statically typed languages.

In Ruby, it would look like this :

x = 0

Ruby sees that x was assigned a number at runtime. Since x was assigned a number, Ruby automatically knows that x must be a Fixnum.

How does it work?


First, we need two different objects that have the same method name. However, the method can’t be given to the object via the same superclass, because it would instead be inheritance.

Let’s take a look at a simple example of duck typing.

class Duck
  def quack
    puts "Quack!"
  end
end

class Alien
  def quack
    puts "I'm not a duck, but... Quack!"
  end
end

def try_quack(duck)
  duck.quack
end

try_quack(Duck.new)
try_quack(Alien.new)

Output :

Quack!
I'm not a duck, but... Quack!

How did Ruby know?


In Ruby’s mind, the Alien instance and the Duck instance are essentially the same. When we called the try_quack method, Ruby wanted an object that had a quack method.

In this case, when we passed in the Duck instance, Ruby saw that the Duck object would quack, so it called the Duck instance’s quack method.

For the Alien, even though the Alien class has nothing to do with the Duck class, it still has a quack method. As a result, Ruby happily calls the Alien class’s quack method.

Conclusion


Duck typing is a powerful feature of Ruby that allows you to call methods on seemingly different objects, as long as those objects have the same method names. As a result, there is no need for inheritance. You simply call the method, and if the object has it, it will work.

Ruby doesn’t care who the object is, but rather what it is.

Advertisements