Module and Mixin revisited
From the feedback I got from ruby on rails course, there seem to be many students who find many core concept of ruby difficult to understand. So, the course mailing thread aside, I’ll try my best to explain some of these concept in depth here. This post will be about the concept of Mixin and ruby Module.
Mixin and Module
Wikipedia offers one of the best description of what mixin is.
“In OO languages, a mixin is a class that provides a certain functionality to be inherited by a subclass, but is not meant to stand alone. Inheriting from a mixin is not a form of specialization but is rather a means to collect functionality. A class may inherit most or all of its functionality by inheriting from one or more mixins through multiple inheritance.” - Wikipedia
Ruby’s flavor of mixin comes in the form of Module. Module is a collection of methods and constant. The most commonly use of module is to have its members (methods, features) “mixed” into a class. The most evident example is the Kernel methods that are mixed-in to Object class. Because of this, methods from Kernels are universally available to all ruby objects.
Basic example
In the last post, I showed an example of ‘puts’ method. ‘puts’ is available to all Object in Ruby. ‘puts’ exists in Kernel module, and Kernel is mixed into Object class. Now since everything in ruby is an Object, they also automatically have access to ‘puts’ in Kernel module.
puts "string".class.ancestors
# [String,Enumerable,Comparable,Object,Kernel]
puts Object.class.ancestors
# [Class,Module,Object,Kernel]
puts Object.private_methods.include?('puts')
# true => Object has 'puts' method as member
puts Object.class.private_methods(false).include?('puts')
# false => 'puts' is inherited member
puts Kernel.class.private_methods.include?('puts')
# true => 'puts' is a member of Kernel module
Another example is the use of Math module. you can access Math’s constant value without having to include Math module
puts Math::PI
# 3.141592653589793
puts Math.sqrt(256)
# 16
Matz has called the mix-in feature of module “single inheritance with implementation sharing“. It’s a way of getting benefit of multiple inheritance without the mess and difficulties.
Module instance method
With “include” keyword, the modules methods become available as object’s instance methods. You can think of including Ruby module to a class is similar to appending functions of that module to an object.
module MyModule def instance_method puts 'this is MyModule instance_method' end end
class MyClass include MyModule end
my_class = MyClass.new my_class.instance_method #this is MyModule instance_method
As you can see, with ‘include‘ keyword, MyModule’s method becomes available to all instance of MyClass object.
Module class method with append_features
It’s also possible to make module methods available to class. What we’re going to use is ‘append_features‘. By overriding module’s ‘append_features' method with class as parameter, nested method under append_features will be accessible to that class.
module MyModule def MyModule.append_features(childClass) def childClass.classMethod puts 'MyModule classMethod' end super #HAVE to call super here end def instance_method puts 'this is MyModule instance_method' end end
my_class = MyClass.new my_class.classMethod # illegal MyClass.classMethod # print MyModule classMethod
A few things to note here. First,’append_features‘ actually do the work equivalent to include operation. Therefore, we need to call super. Otherwise, the rest of the code in the module wouldn’t be included at all. Another thing, the nested method can only be singleton/static method.
Module class method with inheritance
Alternative to using append_features, you can mix in module’s instance methods as class methods with inheritance
class MyOtherClass class << self include MyModule end end
MyOtherClass.instance_method # print this is MyModule instance_method # instance_method becomes class method
As you can see, the ruby language itself is very powerful. But by nature, it still follows the Object Oriented principle. On the future post, I’ll review the concept of blocks and lambda expression.
Teera on July 29th 2008 in Software Development, Ruby

























