class Test def self.inherited(child) # child.overrided_methods??? end def self.foo end def self.bar end end def Child < Test def self.bar puts "bar" end end
加载Test的子类时调用self.inherited方法。所以我在child中引用了这个子类,但我不知道如何获得被这个子类重写的方法。
有什么想法吗?
-
Arsen建议使用self.method_added(name)而不是self.inherited(child),但是这个方法只捕获实例方法,我想捕获类方法。有没有人知道用类方法做同样事情的另一种方法? 在最后一种情况下,我会考虑使用单例并将所有这些类方法转换为实例方法,然后问题就解决了。
答案 0 :(得分:2)
例如,方法可以覆盖Object::method_added(name)
方法,类似于您使用的“继承”方法:
class test
def self.method_added(name)
puts "method_added(#{name.inspect})"
super
end
end
irb(main):002:0> class Child < Test; def foo; end; end
method_added(:foo)
=> nil
然后,您可以将收到的名称与方法列表进行比较:
Test.instance_methods.include?(name.to_s)
使用类方法这种方法不起作用(即使你做了class << self
魔法之类的事情),但是一个有帮助的人知道答案:http://www.ruby-forum.com/topic/120416:
class Test
def self.singleton_method_added(name)
puts "Class method added #{name.inspect}"
end
end
这只是问题的第一部分,因为您需要知道哪个类定义了方法(它将是self)以及该方法是新方法还是重写方法。试用这段代码:
class Test
def self.singleton_method_added(name)
if self == Test
puts "My own class method added: #{self.name}.#{name.inspect}"
elsif Test.methods(false).include?(name.to_s)
puts "Class method overriden: #{self.name}.#{name.inspect}"
elsif Test.methods(true).include?(name.to_s)
puts "My parent's class method overriden: #{self.name}.#{name.inspect}"
else
puts "New class method added: #{self.name}.#{name.inspect}"
end
end
end
答案 1 :(得分:0)
也许是解决方案的第一步:
通过调用child.instance_method(:bar)
(如果孩子引用该类)或child.method(:bar)
(如果它引用了Child的实例),您可以获得UnboundMethod
或Method
个对象代表你的方法:
a = Test.instance_method(:foo)
b = Child.instance_method(:foo)
不幸的是,a == b
的计算结果为false,尽管两者都指的是相同的方法。
答案 2 :(得分:0)
def overridden_methods
klass = self.class
klass.instance_methods.select {|m| klass.instance_method(m).owner == klass}
end
根据您的需要进行更改。