Module methods (those methods specifically preceded by the module name) can help protect your code from accidental name conflicts. However, no such protection is given by instance methods within modules. Let’s suppose you have two modules—one called Happy
and the other called Sad
. They each contain a module method called mood
and an instance method called expression
.
happy_sad.rb
module Happy def Happy.mood # module method return "happy" end def expression # instance method return "smiling" end end module Sad def Sad.mood # module method return "sad" end def expression # instance method return "frowning" end end
Now a class, Person, includes both these modules:
class Person include Happy include Sad attr_accessor :mood def initialize @mood = Happy.mood end end
The initialize
method of the Person class needs to set the value of its @mood
variable using the mood
method from one of the included modules. The fact that they both have a mood
method is no problem; being a module method, mood
must be preceded by the module name so Happy.mood
won’t be confused with Sad.mood
.
But both the Happy
and Sad
modules also contain a method called expression
. This is an instance method, and when both the modules are included in the Person class, the expression
method can be called without any qualification:
p1 = Person.new puts(p1.expression)
Which expression
method is object p1
using here? It turns out that it uses the method last defined. In the example case, that happens to be the method defined in the Sad
module for the simple reason that Sad
is included after Happy
. So, p1.expression
returns “frowning.” If you change the order of inclusion so that Happy
is included after Sad
, the p1
object will use the version of the expression
method defined in the Happy module and will display “smiling.”
Before getting carried away with the possibilities of creating big, complex modules and mixing them into your classes on a regular basis, bear this potential problem in mind: Included instance methods with the same name will “overwrite” one another. The problem may be obvious to spot in my little program here. But it may not be so obvious in a huge application!