Metaprogramming Name Collision Experiments with Module Inclusion/Extension

02/24/09

Today I was doing yet another quiz designed to test your ruby/programming skills. If times were less scared and lean, I would probably not even apply for these jobs. My reason being that they rarely test for the qualities of a really good coder. One this week involved looking up formulas in statistics references and plugging in numbers. Looking for a coder that can plug numbers into existing equation is not the same as testing someone for problem solving skills. I think the real issue is that testing for problem solving skills is hard.

Anyway, today I had to solve a metaprogramming quiz. I love metaprogramming, so I was surprised when I learned something new in the quiz. Actually, it was something I hadn’t really thought about which is what wins out when a there is a name collision between a module and a class. Here is code to experiment with.


module Includable
  def identity
    'I am includable'
  end
end

module Extendable
  def identity
    'I am extendable'
  end
end

class Dominant
  def identity
    'I am dominant (on an instance level)'
  end
  
  def self.identity
    'I am dominant (on a class level)'
  end
  
  include Includable
  extend Extendable
end  

puts Dominant.identity # I am dominant (on a class level)
puts Dominant.new.identity # I am dominant (on an instance level)

So, things are as they should be. Methods defined in the class win over module inclusion/extensions. This is true regardless of order, because you can see in the Dominant class that the inclusion and extension of modules happens after the methods are defined.

There is some satisfaction in knowing this. It makes sense in that class defined methods are more specific and customized for the class. Therefore they should win out.