When you call a method on an object, Ruby looks for the implementation of that method. It looks in the following places and uses the first implementation it finds:
- Methods from the object's singleton class (an unnamed class that only exists for that object)
- Methods from prepended modules (Ruby 2.0+ feature)
- Methods from the object's class
- Methods from included modules
- Methods from the class hierarchy (superclass and its ancestors)
Example
Let's say we have the following class hierarchy:
class Superclass
def action
puts "Superclass"
end
end
module IncludedModule
def action
puts "Included module"
super
end
end
module PrependedModule
def action
puts "Prepended module"
super
end
end
module SingletonModule
def action
puts "Singleton class"
super
end
end
class Klass < Superclass
include IncludedModule
prepend PrependedModule
def action
puts "Klass"
super
end
end
... and we call a method like this:
instance = Klass.new
instance.extend(SingletonModule)
instance.action
Then we get an output as expected:
Singleton class
Prepended module
Klass
Included module
Superclass
If you are interested in why it works like that, you will find some more background here.
Posted by Henning Koch to makandra dev (2014-03-17 10:06)