0

我正在创建一个ActiveSupport::Concern,它使用该方法定义了几个类方法class_methods。使用常规模块,可以直接使用调用类方法NameOfModule.target_method(例如,在 stdlib 类 Math 中调用acos是很常见的Math.acos(x)),但我不知道如何执行类似的调用 my Concern. 这可能吗,如果可以,怎么做?

4

1 回答 1

1

不,你不能,因为块中定义的方法class_methods实际上是在模块中定义的Foo::ClassMethodsFoo你关心的是)。这是相关的源代码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 回答