我可以从 ActiveRecord::Concern 中调用 class 方法而不将其混合到另一个 class 中吗?
Can I invoke a class method from an ActiveRecord::Concern without mixing it into another class?
我正在创建一个 ActiveSupport::Concern that defines several class methods using the class_methods
method. With a regular module it is possible to invoke the class methods directly using NameOfModule.target_method
(e.g. in the stdlib class Math it's common to invoke acos 像这样 Math.acos(x)
) 但我不知道如何执行类似的调用我的 Concern
。这可能吗,如果可能的话,怎么做到的?
不,你不能,因为 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
将由包含您关注的 class 扩展。相关源代码如下:
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
我正在创建一个 ActiveSupport::Concern that defines several class methods using the class_methods
method. With a regular module it is possible to invoke the class methods directly using NameOfModule.target_method
(e.g. in the stdlib class Math it's common to invoke acos 像这样 Math.acos(x)
) 但我不知道如何执行类似的调用我的 Concern
。这可能吗,如果可能的话,怎么做到的?
不,你不能,因为 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
将由包含您关注的 class 扩展。相关源代码如下:
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