[英]How to check method_defined? from a module thats used in class with a method defined after the module is included
How can I define a module that checks the existence of an instance method in the class the module is used.如何定义一个模块来检查使用该模块的 class 中是否存在实例方法。 The module is normally included at the start of the file while methods are defined afterwards.该模块通常包含在文件的开头,而方法是在之后定义的。 I'm using Rails.我正在使用 Rails。
A module with a hook带钩子的模块
module MyModule
extend ActiveSupport::Concern
included do
raise "Foo" if method_defined? :bar
end
end
A Foo
error is never raised in the following code, how can I get this to raise the error?以下代码中从未引发Foo
错误,我怎样才能得到它来引发错误?
class MyClass
include MyModule
def bar
puts "Hello from Bar"
end
end
A Foo
error IS raised in the following code:以下代码中引发了Foo
错误:
class MyOtherClass
def bar
puts "Hello from Bar"
end
include MyModule
end
This is a pure-Ruby answer.这是一个纯 Ruby 的答案。 I don't know if Rails supports callbacks that are not supported by Ruby that would be useful here.我不知道 Rails 是否支持 Ruby 不支持的回调,这在这里有用。
As @Amadan notes, the module is not a mind-reader;正如@Amadan 所说,该模块不是读心器; to see an instance method defined on the class the method needs to be defined before the module is included.要查看在 class 上定义的实例方法,需要在包含模块之前定义该方法。 The method Module#included takes as an argument the module in which it being included.方法Module#included将包含它的模块作为参数。 It needs that because self
is MyModule
when that method is executed.它需要它,因为执行该方法时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
prints印刷
self = MyModule
:bar is defined
:goo is defined
Note that Module#included
is executed after the instance method defined in MyModule
( goo
) is included in MyClass
.注意Module#included
是在MyModule
( goo
) 中定义的实例方法被包含在MyClass
之后执行的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.