检测到方法未被覆盖

时间:2009-11-08 19:56:17

标签: ruby metaprogramming

说,我有以下两个班级:

class A
  def a_method
  end
end

class B < A
end

是否可以从B类的(实例)中检测到超级类中定义的方法a_method ,因此不会在B中被覆盖?

更新:解决方案

虽然我已经将Chuck的答案标记为“已接受”,但后来Paolo Perrota让我意识到该解决方案显然可以更简单,并且它也可能适用于早期版本的Ruby。

检测B中是否覆盖了“a_method”:

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

对于类方法,我们同样使用singleton_methods

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

4 个答案:

答案 0 :(得分:7)

如果您使用的是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

答案 1 :(得分:2)

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"]

答案 2 :(得分:0)

您可以随时查看以下内容并查看其中是否已定义:

a = A.new

a.methods.include?(:method)

答案 3 :(得分:0)

如果对象bB的一个实例,您可以测试b的直接超类是否a_method

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

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

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

相关问题