Hi --

On Wed, 30 Aug 2006, John W. Long wrote:

> 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?

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

-- 
                   David A. Black | dblack / wobblini.net
Author of "Ruby for Rails"   [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog)        [2] | Co-director, Ruby Central, Inc.   [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com    | [4] http://www.rubycentral.org