AmanKing

How mixins workControl PanelChange LogBrowse PagesSearch?

How mixins work

An entry in Jay Fields' blog set me thinking about how mixins work in Ruby... I found the answer in Programming Ruby (an excellent Ruby resource):

If a module is included within a class definition, the module's constants, class variables, and instance methods are effectively bundled into an anonymous (and inaccessible) superclass for that class. In particular, objects of the class will respond to messages sent to the module's instance methods.

This explained a few things but set me thinking on how multiple includes of different modules is handled for a class... I wrote the following snippet to test it out...

module Aman
protected
   def hi
       "hi"
   end
end
 
module King
protected
   def hi
       "bye"
   end
end
 
class AmanKing
   include Aman
   include King
end
 
a=AmanKing.new
# a.hi # NoMethodError: protected method `hi' called for #<AmanKing:0x4e86e54>
 
class AmanKing
   def hi
       super
   end
end
 
puts a.hi # => "Bye"
 
puts AmanKing.ancestors.join(", ") # => AmanKing, King, Aman, Object, Kernel
 
puts AmanKing.superclass # => Object

Previous partly-incorrect explanation by me:
The code shows that (1) there is only one (anonymous) superclass created, (2) access modifiers like protected are honoured for modules, and (3) an included module overwrites any method with same name that may have been included before.

Proper explanation from another entry by Jay:

  1. there is a sequence of ancestors created for the class that includes modules, and their ordering is according to the order of module inclusion and original class hierarchy (see example code above)
  2. the superclass of the class that includes modules, however, still remains the same as if the class had not included modules, ie, a module cannot act as a superclass
  3. access modifiers like protected are honoured for modules (acting as ancestors)
  4. a module included into a class does not overwrite methods with same names provided by modules included earlier -- however a newer included module does hide methods with same names introduced by previous modules. This is explained by the first point.

Quite a whirlwind of info, isn't it? Smile

Tags: technology:ruby Last modified 11:55 Mon, 27 Aug 2007 by AmanKing. Accessed 185 times Children What Links Here share Share Except where expressly noted, this work is licensed under a Creative Commons License.