在使用Ruby on Rails ActiveSupport :: Concern功能时如何"嵌​​套"模块的包含?

Bac*_*cko 7 ruby nested module ruby-on-rails include

我正在使用Ruby 1.9.2和Ruby on Rails v3.2.2 gem.我希望"嵌套"包含模块,因为我使用的是RoR ActiveSupport :: Concern功能,但我怀疑我应该在哪里说明该include方法.也就是说,我有以下内容:

module MyModuleA
  extend ActiveSupport::Concern

  # include MyModuleB

  included do
    # include MyModuleB
  end
end
Run Code Online (Sandbox Code Playgroud)

应该include MyModuleB在"身体"/"上下文"/"范围"中说明,MyModuleA或者我应该在included do ... end块中说明?有什么区别,我应该从中得到什么?

Chr*_*ald 19

如果你包含MyModuleB在"body"中MyModuleA,那么模块本身就是用B的功能扩展的.如果将其包含在included块中,则它将包含在混合的类中MyModuleA.

那是:

module MyModuleA
  extend ActiveSupport::Concern
  include MyModuleB
end
Run Code Online (Sandbox Code Playgroud)

产生类似的东西:

MyModuleA.send :include, MyModuleB
class Foo
  include MyModuleA
end
Run Code Online (Sandbox Code Playgroud)

module MyModuleA
  extend ActiveSupport::Concern
  included do
    include MyModuleB
  end
end
Run Code Online (Sandbox Code Playgroud)

产生类似的东西:

class Foo
  include MyModuleA
  include MyModuleB
end
Run Code Online (Sandbox Code Playgroud)

原因是这ActiveSupport::Concern::included类似于:

def MyModuleA
  def self.included(klass, &block)
    klass.instance_eval(&block)
  end
end
Run Code Online (Sandbox Code Playgroud)

included块中的代码在包含类的上下文中运行,而不是在模块的上下文中运行.因此,如果MyModuleB需要访问它所混入的类,那么你需要在included块中运行它.否则,它实际上是一样的.

通过演示:

module A
  def self.included(other)
    other.send :include, B
  end
end

module B
  def self.included(other)
    puts "B was included on #{other.inspect}"
  end
end

module C
  include B
end

class Foo
  include A
end

# Output:
# B was included on C
# B was included on Foo
Run Code Online (Sandbox Code Playgroud)