Friday, August 1, 2008

Apparently code order matters in Ruby

I was recently working on some code that had a structure like this:

module OuterModule
class MyObject
include InnerModule
end

module InnerModule
def hello
"hello"
end
end
end

include OuterModule

m = MyObject.new

puts m.hello

When I ran it, I would get this unfortunate output:

test_ruby_class_heirarchy.rb:3: uninitialized constant OuterModule::MyObject::InnerModule (NameError)

I'm too embarrased to list all the voodoo I tried to get this to work, but simply putting the definition of MyObject below that of InnerModule did the trick:

module OuterModule
module InnerModule
def hello
"hello"
end
end

class MyObject
include InnerModule
end
end

include OuterModule

m = MyObject.new

puts m.hello

This gives me the expected output:

hello

Going into this, I would have never guessed that the order in which I defined things would have this effect.