OdeToCode IC Logo

Ruby: initialize and super

Tuesday, July 13, 2010

One of the reasons to like Ruby if you come from a C#/C++/Java background is how certain constructs will tend to "just make sense" even though Ruby will throw in a twist here and there.

Consider the case of inheritance and initialize methods.

class Employee < Person
end

emp = Employee.new

Let's say you run the code and get an error on the line of code creating the Employee object : "wrong number of arguments". Seems odd, because Employee doesn't look like it needs an argument for creation, but then you poke around and find the definition for Person (the base class).

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

Ah, so we need a name to build a person object. The C# developer might instantly think of this scenario:

class Person
{
    public Person(string name)
    {
        this.name = name;
    }

    string name;
}

class Employee : Person
{
}

 

With C# you have to give Employee a constructor that will forward a name parameter to the base constructor.

class Employee : Person
{
    public Employee(string name) : base(name)
    {            
    }
}

In Ruby you can take this approach, too. It's a good approach if you need to perform some extra initialization for employees, like require a salary figure.

class Employee < Person
    def initialize(name, salary)
        super(name)
        @salary = salary
    end
end

emp = Employee.new("Chuck", 100)

It's Ruby's super keyword that acts like the base keyword in C#. The twist here is how Ruby will just make things work in the trivial case.

class Employee < Person
end

emp = Employee.new("Chuck")

In this code, "Chuck" will arrive at the initialize method of Person without any explicit code from us.

You might call it magic, or you might call it wonderful.