检测一个方法未被覆盖
说,我有以下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
可以随时以下,看看它的存在定义:
a = A.new
a.methods.include?(:method)
的OP被询问如何检测*从类B *内,如果它覆盖方法或没有。 知道类A定义的方法并没有说类B是否重写它。 – 2009-11-08 20:10:38
这很好,但是如何另外检测该方法是否(最初)包含在B的实例方法中? – mxgrn 2009-11-08 20:12:50
在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"]
非常酷,谢谢!看到最初提到的Ruby版本后,特别高兴从1.9降低到1.8.7(我实际使用它)。 – mxgrn 2009-11-08 23:34:55
是的,我对此有点模糊。起初我认为它与1.8.7一起工作,然后看到'Method#owner'不在1.8.7 ri文档中,所以我将它改为1.9,然后我实际检查了1.8.7中是否存在该方法,并看到我第一次做对了。很高兴它有帮助。 – Chuck 2009-11-08 23:55:10