I've just faced this behavior I don't really understand.
module M
def foo
"module_foo"
end
end
class C
def foo
"class_foo"
end
include M
end
puts C.new.foo
Why does C.new.foo
actually return class_foo
? I was pretty much sure that method should be overridden by the one in module. Another thing, replacing "class_foo"
with super
makes C.new.foo
return `"module_foo"
That actually looks like module is somehow included before the class instance method is defined. Could you please clarify?
From Programming Ruby section on mixins:
In fact, mixed-in modules effectively behave as superclasses.
So what you experience is normal. your Module M is a superclass of your class C
Therefore your foo method in class C overrides the foo method in module M
Here's how ruby does method lookup:
You can find more details here: http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html
Therefore, to find a method, Ruby goes in the receiver's class, and from there it climbs the ancestors chain until it finds the method. This behavior is also called the "one step to the right, then up" rule: Go one step to the right into the receiver's class, and then up the ancestors chain, until you find the method. When you include a module in a class (or even in another module), Ruby creates an anonymous class that wraps the module, and inserts the anonymous class in the chain, just above the including class itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With