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

F

Francis Hwang

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/
 
A

Austin Ziegler

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

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
 
T

ts

A> class << klass
A> define_method:)singleton_method_added) do |sym|

???

def klass.singleton_method_added(sym)
# no ?
end


Guy Decoux
 
R

Robert Klemme

Francis Hwang said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top