Don’t use the constructor before initialize is defined

Problem

If for some reason, most likely convenience, you want to have a constant containing an instance of an object in your class you have to pay attention to where you define this constant. An example might be that instead of City.new(10, 5) you would want to refer to it as the constant CITY_A.

(Please be aware that I adjusted the example a bit since I didn’t want to give away information about the ThoughtWorks coding test, it made more sense in its original application but just run with it.)

Fair enough so let’s give it a shot:

class City

CITY_A = City.new 10, 5

def initialize x, y
@x = x
@y = y
end

# rest of the class omitted

end

Now awkwardly enough when we try to let ruby interpret this code we get the following error (the error looks different depending on your interpreter, this is Ruby 1.9.3 roughly the same happens with JRuby and Rubinius):

city.rb:3:in `initialize': wrong number of arguments(2 for 0) (ArgumentError)
from city.rb:3:in `new'
from city.rb:3:in `<class:City>'
from city.rb:1:in `<main>'

But we have an initialize method and it takes 2 arguments! So why does the Ruby interpreter claim that it doesn’t take arguments at all?

Solution

So what’s wrong? Well we have to know how the ruby interpreter works. It starts at the top of the class and there it doesn’t yet know that we have an all new initialize method, taking 2 parameters. So fixing this is quite easy, here is the fixed class:

class City

def initialize x, y
@x = x
@y = y
end

CITY_A = City.new 10, 5

# rest of the class omitted

end

As you can see the constant declaration was moved beneath the declaration of the initialize method. While I prefer to define constants at the very top of my classes, this is the only method (known to me) to make this code work.

On a side note, this is a simplified example my actual use for class instances in a constant was a bit more complex and an adjusted version may be seen in my next blog post.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s