检测一个方法未被覆盖

问题描述:

说,我有以下2类:检测一个方法未被覆盖

class A 
    def a_method 
    end 
end 

class B < A 
end 

是否有可能从(的实例)类B中方法a_method在所定义的范围内检测超类,因此不会在B中被覆盖?

更新:解决方案

虽然我已经打上查克的回答是“接受”,后来保罗Perrota让我意识到,该解决方案能够明显更简单,而且它可能会与早期版本的工作Ruby也是。

检测是否“a_method”在B被覆盖:

B.instance_methods(false).include?("a_method") 

而对于类方法,我们使用singleton_methods类似:

B.singleton_methods(false).include?("a_class_method") 

如果您使用的是Ruby 1.8.7或更高版本,使用Method#owner/UnboundMethod#owner很容易。

class Module 
    def implements_instance_method(method_name) 
    instance_method(method_name).owner == self 
    rescue NameError 
    false 
    end 
end 
+0

非常酷,谢谢!看到最初提到的Ruby版本后,特别高兴从1.9降低到1.8.7(我实际使用它)。 – mxgrn 2009-11-08 23:34:55

+0

是的,我对此有点模糊。起初我认为它与1.8.7一起工作,然后看到'Method#owner'不在1.8.7 ri文档中,所以我将它改为1.9,然后我实际检查了1.8.7中是否存在该方法,并看到我第一次做对了。很高兴它有帮助。 – Chuck 2009-11-08 23:55:10

可以随时以下,看看它的存在定义:

a = A.new 

a.methods.include?(:method) 
+0

的OP被询问如何检测*从类B *内,如果它覆盖方法或没有。 知道类A定义的方法并没有说类B是否重写它。 – 2009-11-08 20:10:38

+0

这很好,但是如何另外检测该方法是否(最初)包含在B的实例方法中? – mxgrn 2009-11-08 20:12:50

+0

在b中,你仍然可以看到A是否响应该方法,如果是这样,B定义了相同的方法,那么它明显优先于A的实现 – ennuikiller 2009-11-08 20:14:59

给定一个对象b这是一个实例B,你可以测试一下,看看b的直接超类是否有a_method

b.class.superclass.instance_methods.include? 'a_method' 

注意,测试是针对方法的名称,而不是一个符号或方法的对象。

“因此没有被覆盖在B” - 只要知道仅在规定的方法是困难的,因为你可以在A和B的单个实例定义的方法......所以我认为这将难以测试a_method仅在A上定义,因为您必须整理系统中的所有子类和子类并对它们进行测试...

class A 
    def m1; end 
    def m2; end 
end 

class B < A 
    def m1; end 
    def m3; end 
end 

obj = B.new 
methods_in_class = obj.class.instance_methods(false) # => ["m1", "m3"] 
methods_in_superclass = obj.class.superclass.instance_methods(false) # => ["m2", "m1"] 
methods_in_superclass - methods_in_class # => ["m2"]