我正在创建一个ActiveSupport::Concern,它使用该方法定义了几个类方法class_methods
。使用常规模块,可以直接使用调用类方法NameOfModule.target_method
(例如,在 stdlib 类 Math 中调用acos是很常见的Math.acos(x)
),但我不知道如何执行类似的调用 my Concern
. 这可能吗,如果可以,怎么做?
问问题
95 次
1 回答
1
不,你不能,因为块中定义的方法class_methods
实际上是在模块中定义的Foo::ClassMethods
(Foo
你关心的是)。这是相关的源代码ActiveSupport::Concern
module ActiveSupport
# ...
module Concern
# ...
def class_methods(&class_methods_module_definition)
mod = const_defined?(:ClassMethods, false) ?
const_get(:ClassMethods) :
const_set(:ClassMethods, Module.new)
mod.module_eval(&class_methods_module_definition)
end
end
end
您可以看到,如果它不是您自己定义的,它class_methods
只是为您创建模块。ClassMethods
您定义的方法只是该模块中的实例方法,因此您不能在模块级别调用它。
稍后,该模块ClassMethods
将由包含您关注的类扩展。以下是相关的源代码:
module ActiveSupport
# ...
module Concern
def append_features(base)
if base.instance_variable_defined?(:@_dependencies)
# ...
else
# ...
base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) # <-- Notice this line
# ...
end
end
end
end
于 2016-08-03T02:29:36.653 回答