How do I override a class method on an object with another module? For
example:
class TestObject
def self.my_method
“override me”
end
end
module TestExtension
def my_method
“overridden by TestExtension”
end
def another_method
“another method”
end
end
TestObject.extend TestExtension
puts TestObject.my_method #=> “override me”
puts TestObject.another_method #=> “another method”
Why can’t I get TestObject to use my_method from TestExtension?
John W. Long wrote:
def my_method
puts TestObject.another_method #=> “another method”
Why can’t I get TestObject to use my_method from TestExtension?
Because we don’t have Cuts 
Okay a more presently practical answer. You can use a hack like:
module TestExtension
def self.included(base)
base.module_eval do
def my_method
"overridden by TestExtension"
end
end
end
def another_method
"another method"
end
end
T.
Trans wrote:
def another_method
"another method"
end
end
Mmm. That doesn’t work either.
On 8/30/06, John W. Long [email protected] wrote:
Trans wrote:
Okay a more presently practical answer. You can use a hack like:
module TestExtension
def self.included(base)
shouldn’t be “extended” ?
Hi –
On Wed, 30 Aug 2006, John W. Long wrote:
def my_method
puts TestObject.another_method #=> “another method”
Why can’t I get TestObject to use my_method from TestExtension?
What you’re seeing is that in the method lookup path, a given class
comes before any modules it includes. In your case, the class in
question is the singleton class of TestObject: that class defines
#my_method, and also includes a module that defines #my_method. The
one defined in the class “wins”.
Here’s another, parallel example:
module M
def my_method
puts “M#my_method”
end
end
class C
end
c = C.new
class << c # defined the method in the class
def my_method
puts “C#my_method”
end
end
c.extend(M) # also include the module in the class
c.my_method # “C#my_method” (the class wins)
The module would win if the method were defined in the class of the
object, rather than the singleton class – because then the lookup
order would be:
singleton class (no)
module included by singleton class (yes – execute method)
[class (never reached)]
David
That works. So the final code would be something like:
module TestExtension
def inject_methods(base)
base.module_eval do
def self.my_method
“overridden by TestExtension”
end
end
end
def extended(base)
inject_methods(base)
end
def included(base)
inject_methods(base)
end
end
This has always been a little clunky in Ruby, primarily because
methods written within a specific class were designed to override
mixin and parent class methods, not vice-versa.