Getting a callback whenever a class method is added to a class or its children?

Is there a way to capture whenever a class method is added either to a base class or its children? For example, if my code is

class A
   def self.some_method
     ...
   end
end

class B < A
   def self.some_method
     ...
   end
end

I want to be notified twice. Defining A.singleton_method_added only seems to work for the definition of A.some_method, but won't catch the definition of B.some_method.

Francis Hwang
http://fhwang.net/

This seems to work, but it provides interesting results:

    class A
      class << self
        def singleton_method_added(sym)
          puts "+++A.#{sym}"
        end

        def inherited(klass)
          class << klass
            define_method(:singleton_method_added) do |sym|
              puts "++#{self}.#{sym}"
              super
            end
          end
        end
      end
    end

    class B < A
      def foo
        puts "Bfoo"
      end
    end

    def A.foo; puts "Afoo"; end

    class C < B; end
    def C.foo; puts "Cfoo"; end

C:\home>inherit.rb
+++A.singleton_method_added
+++A.inherited
++B.singleton_method_added
+++A.B
+++A.foo
++C.singleton_method_added
++C.C
+++A.B
++C.foo
++C.C
+++A.B

C:\home>ruby -v
ruby 1.8.2 (2004-07-29) [i386-mswin32]

-austin

···

On Mon, 29 Nov 2004 22:49:57 +0900, Francis Hwang <sera@fhwang.net> wrote:

Is there a way to capture whenever a class method is added either to a
base class or its children? For example, if my code is

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

"Francis Hwang" <sera@fhwang.net> schrieb im Newsbeitrag
news:47FE7E9A-420E-11D9-960B-000A95DBF456@fhwang.net...

Is there a way to capture whenever a class method is added either to a
base class or its children? For example, if my code is

class A
   def self.some_method
     ...
   end
end

class B < A
   def self.some_method
     ...
   end
end

I want to be notified twice. Defining A.singleton_method_added only
seems to work for the definition of A.some_method, but won't catch the
definition of B.some_method.

Of course, as it's defined for A only and not for B. You can define
singleton_method_added in class Class - then it will catch *all* singleton
methods defined for class instances.

class Class
  def singleton_method_added(sym)
    puts "singleton added to #{self}: #{sym}"
  end
end

class A
   def self.some_method
     # ...
   end
end

class B < A
   def self.some_method
     # ...
   end
end

Or you can define a module for this:

module SingletonAware
  def singleton_method_added(sym)
    puts "singleton added to #{self}: #{sym}"
  end
end

class A
   extend SingletonAware

   def self.some_method
     # ...
   end
end

class B < A
   extend SingletonAware

   def self.some_method
     # ...
   end
end

With a bit more magic you can even safe the "extend SingletonAware" for
class B.

Kind regards

    robert

          class << klass
            define_method(:singleton_method_added) do |sym|

???

             def klass.singleton_method_added(sym)
                # no ?
             end

Guy Decoux