问题描述
如何定义一个模块来检查使用该模块的类中是否存在实例方法。模块通常包含在文件的开头,而方法是在之后定义的。我正在使用 Rails。
带钩子的模块
module MyModule
extend ActiveSupport::Concern
included do
raise "Foo" if method_defined? :bar
end
end
class MyClass
include MyModule
def bar
puts "Hello from Bar"
end
end
class MyOtherClass
def bar
puts "Hello from Bar"
end
include MyModule
end
解决方法
这是一个纯 Ruby 的答案。我不知道 Rails 是否支持 Ruby 不支持的回调,这在这里很有用。
正如@Amadan 所指出的,该模块不是读心者;要查看在类上定义的实例方法,需要在包含模块之前定义该方法。方法 Module#included 将包含它的模块作为参数。它需要它,因为执行该方法时 self
是 MyModule
。
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
是在MyModule
(goo
)中定义的实例方法包含在MyClass
之后执行的。