如何检测包含的模块方法将被覆盖?

时间:2016-11-01 16:18:27

标签: ruby

我有一个模块,我想检测并提升它所包含的类是否具有相同名称的实例方法。

module Hello
  def self.included(base)
    puts base.instance_methods.include?(:foo)
  end
end 

如果已定义方法,则模块知道:

class Foo
  def foo; end
  include Hello # => true
end

但是如果方法是在包含之后定义的,就像通常一样,那么它就不知道它的方法被覆盖了:

class Foo
  include Hello # => false
  def foo; end
end

2 个答案:

答案 0 :(得分:0)

AFAIK在阅读/解释此行时,无法知道include Hello行下方的内容。

意思是,在使用Foo类执行文件时,在到达该类的最后一个结束end之前,您无法确定它是否有某种方法。

因此,最简单的解决方案是将模块简单地包含在类定义的底部。

答案 1 :(得分:0)

首先:这听起来像非常糟糕的主意。继承是一个重要的特征,你为什么要禁止它呢?

您需要检测何时添加方法。您可以使用method_added方法。像这样:

module Hello
  def self.included(base)
    puts base.instance_methods.include?(:foo)
    base.singleton_class.prepend(MethodBlocker)
  end

  module MethodBlocker
    def method_added(meth)
      puts 'foo method overridden' if meth == :foo
      super # see, inheritance is a Good Thing!
    end
  end
end

class Foo
  include Hello # => false
  def foo; end
end
# false
# foo method overridden
相关问题