---
title: 'Back to Basics: Polymorphism and Ruby'
teaser: An in-depth look at polymorphism over inheritance in Ruby.
tags: web,back to basics,ruby
author: Britt Ballard
published_on: 2014-03-14
---

> Polymorphism
> - the provision of a single interface to entities of different types

Polymorphism is one of the fundamental features of object oriented programming,
but what exactly does it mean? At its core, in Ruby, it means being able to send
the same message to different objects and get different results. Let's look at a
few different ways to achieve this.

## Inheritance

One way we can achieve polymorphism is through inheritance. Let's use the
[template method](http://en.wikipedia.org/wiki/Template_method_pattern) to
create a simple file parser.

First let's create a `GenericParser` class that has a `parse` method. Since
this is a template the only thing this method will do is raise an exception:

```ruby
class GenericParser
  def parse
    raise NotImplementedError, 'You must implement the parse method'
  end
end
```

Now we need to make a `JsonParser` class that inherits from `GenericParser`:

```ruby
class JsonParser < GenericParser
  def parse
    puts 'An instance of the JsonParser class received the parse message'
  end
end
```

Let's create an `XmlParser` to inherit from the `GenericParser` as well:

```ruby
class XmlParser < GenericParser
  def parse
    puts 'An instance of the XmlParser class received the parse message'
  end
end
```

Now let's run a script and take a look at how it behaves:

```ruby
puts 'Using the XmlParser'
parser = XmlParser.new
parser.parse

puts 'Using the JsonParser'
parser = JsonParser.new
parser.parse
```

The resulting output looks like this:

    Using the XmlParser
    An instance of the XmlParser class received the parse message

    Using the JsonParser
    An instance of the JsonParser class received the parse message

Notice how the code behaves differently depending on which child class receives
the `parse` method. Both the <abbr title="Extensible Markup Language">XML</abbr>
and <abbr title="JavaScript Object Notation">JSON</abbr> parsers modify
`GenericParser`'s behavior, which raises an exception.

## Duck Typing

In statically typed languages, runtime polymorphism is more difficult to achieve.
Fortunately, with Ruby we can use [duck typing](http://en.wikipedia.org/wiki/Duck_typing).

We'll use our <abbr title="Extensible Markup Language">XML</abbr> and <abbr
title="JavaScript Object Notation">JSON</abbr> parsers again for this example,
minus the inheritance:

```ruby
class XmlParser
  def parse
    puts 'An instance of the XmlParser class received the parse message'
  end
end

class JsonParser
  def parse
    puts 'An instance of the JsonParser class received the parse message'
  end
end
```

Now we'll build a generic parser that sends the `parse` message to a parser
that it receives as an argument:

```ruby
class GenericParser
  def parse(parser)
    parser.parse
  end
end
```

Now we have a nice example of duck typing at work. Notice how the `parse`
method accepts a variable called `parser`. The only thing required for this to
work is the `parser` object has to respond to the `parse` message and luckily
both of our parsers do that!

Let's put together a script to see it in action:

```ruby
parser = GenericParser.new
puts 'Using the XmlParser'
parser.parse(XmlParser.new)

puts 'Using the JsonParser'
parser.parse(JsonParser.new)
```

This script will result in the following output:

    Using the XmlParser
    An instance of the XmlParser class received the parse message

    Using the JsonParser
    An instance of the JsonParser class received the parse message

Notice that the method behaves differently depending on the object that
receives it's message. This is polymorphism!

## Decorator Pattern

We can also achieve polymorphism through the use of design patterns. Let's look
at an example using the [decorator pattern](http://en.wikipedia.org/wiki/Decorator_pattern):

```ruby
class Parser
  def parse
    puts 'The Parser class received the parse method'
  end
end
```

We need to change our `XmlParser` to include a constructor that accepts a
parser as an argument. The `parse` method will need to be modified to send the
`parse` message to the parser it receives when constructed:

```ruby
class XmlParser
  def initialize(parser)
    @parser = parser
  end

  def parse
    @parser.parse
    puts 'An instance of the XmlParser class received the parse message'
  end
end
```

We'll make the same change to our `JsonParser`:

```ruby
class JsonParser
  def initialize(parser)
    @parser = parser
  end

  def parse
    puts 'An instance of the JsonParser class received the parse message'
    @parser.parse
  end
end
```

We'll use the decorators to create our normal <abbr title="Extensible Markup
Language">XML</abbr> and <abbr title="JavaScript Object Notation">JSON</abbr>
parsers, but in the last example, we'll do something a little different: use
both decorators to achieve runtime polymorphism:

```ruby
puts 'Using the XmlParser'
parser = Parser.new
XmlParser.new(parser).parse

puts 'Using the JsonParser'
JsonParser.new(parser).parse

puts 'Using both Parsers!'
JsonParser.new(XmlParser.new(parser)).parse
```

This script will give us the following output:

    Using the XmlParser
    The Parser class received the parse method
    An instance of the XmlParser class received the parse message

    Using the JsonParser
    An instance of the JsonParser class received the parse message
    The Parser class received the parse method

    Using both Parsers!
    An instance of the JsonParser class received the parse message
    The Parser class received the parse method
    An instance of the XmlParser class received the parse message

Notice how we're able to change the results of sending the `parse` message
based on the output.

## A Simple Before and After

Now we will look at an intentionally simple example of how taking advantage of
polymorphism can simplify our code. Let's say we had the following classes:

```ruby
class Parser
  def parse(type)
    puts 'The Parser class received the parse method'

    if type == :xml
      puts 'An instance of the XmlParser class received the parse message'
    elsif type == :json
      puts 'An instance of the JsonParser class received the parse message'
    end
  end
end
```

We can simplify our `Parser` class by removing the branch logic thanks to simple
duck typing.  In this particular example we also get the benefit of separating
concerns. Now we have our specific parsing logic encapsulated within their own
classes:

```ruby
class Parser
  def parse(parser)
    puts 'The Parser class received the parse method'
    parser.parse
  end
end

class XmlParser
  def parse
    puts 'An instance of the XmlParser class received the parse message'
  end
end

class JsonParser
  def parse
    puts 'An instance of the JsonParser class received the parse message'
  end
end
```

This example demonstrates that we were able to simplify our class using
polymorphism. We were also able to satisfy the [Single Responsibility
Principle][srp].

[srp]: http://c2.com/cgi/wiki?SingleResponsibilityPrinciple

In the initial version of the code the Parser class determined which parser to
use and then initiated the parsing by instantiating and sending the parse
message to the object. In the latter version this class only sends the parse
method to kick off the process.

Polymorphism is one of the foundational elements of object oriented
programming, but can also be confusing to get a grasp on. Taking the time to
understand it and why it's important is a big step towards writing more
maintainable and extensible code.
