Ruby Pattern: Extend through Include
Ruby modules can be mixed into a class two ways. The first way is to include the module in the class, making all methods in the module available in the class.
Also, a class can extend itself by using a module. (Actually, any object can use a module for extension).
However, the majority of the time modules are used with classes, they are included, not extended. Even if I am writing a module which only adds class methods (and could therefore be used with extend rather than include), I write the module like this:
If you're unfamiliar with modules, the included method is called whenever the module is included in a class. The class the module was included in is passed as the argument.
Writing modules like this is good for consistency. This is the pattern used throughout Rails and most Ruby projects. Next time you need to have a module add a method directly on a class, make it a module that can be included.
module BasicMath def add(number) self + number end end Fixnum.class_eval do include BasicMath end 3.add 4 #=> 7
Also, a class can extend itself by using a module. (Actually, any object can use a module for extension).
module ExtendMe def verbal_object_id "my object id is #{self.object_id}" end end class Person extend ExtendMe end Person.verbal_object_id #=> "my object id is 24339630"
However, the majority of the time modules are used with classes, they are included, not extended. Even if I am writing a module which only adds class methods (and could therefore be used with extend rather than include), I write the module like this:
module ExtendThroughInclude def self.included(klass) klass.extend ClassMethods end def instance_method "this is an instance of #{self.class}" end module ClassMethods def class_method "this is a method on the #{self} class" end end end class Person include ExtendThroughInclude end Person.new.instance_method #=> "this is an instance of Person" Person.class_method #=> "this is a method on the Person class"
If you're unfamiliar with modules, the included method is called whenever the module is included in a class. The class the module was included in is passed as the argument.
Writing modules like this is good for consistency. This is the pattern used throughout Rails and most Ruby projects. Next time you need to have a module add a method directly on a class, make it a module that can be included.
Posted on 2007-04-08 | permalink | del.icio.us
Blog Archive
