首页 > 解决方案 > 如何检查method_defined?来自在类中使用的模块,其中包含模块后定义的方法

问题描述

如何定义一个模块来检查使用该模块的类中是否存在实例方法。该模块通常包含在文件的开头,而方法是在之后定义的。我正在使用 Rails。

带钩子的模块

module MyModule
  extend ActiveSupport::Concern

  included do
    raise "Foo" if method_defined? :bar
  end 
end 

以下代码中Foo永远不会引发错误,我怎样才能让它引发错误?

class MyClass 
   include MyModule

   def bar
     puts "Hello from Bar"
   end 
end 

Foo以下代码中出现错误:

class MyOtherClass 
   def bar
     puts "Hello from Bar"
   end 

   include MyModule
end 

标签: ruby-on-railsrubymodulemixins

解决方案


这是一个纯 Ruby 的答案。我不知道 Rails 是否支持 Ruby 不支持的回调,这在这里有用。

正如@Amadan 所说,该模块不是读心器;要查看在类上定义的实例方法,需要在包含模块之前定义该方法。方法Module#included将包含它的模块作为参数。它需要它,因为selfMyModule执行该方法的时间。

module MyModule
  def self.included(mod)
    puts "self = #{self}"
    puts ":bar is defined" if mod.method_defined? :bar
    puts ":foo is defined" if mod.method_defined? :foo
    puts ":goo is defined" if mod.method_defined? :goo
  end
  def goo
  end  
end 
class MyClass 
  def bar
  end 
  include MyModule
end

印刷

self = MyModule
:bar is defined
:goo is defined

请注意,在( ) 中Module#included定义的实例方法包含在.MyModulegooMyClass


推荐阅读