How to “nest” the inclusion of modules when using the Ruby on Rails ActiveSupport::Concern feature?

孤街浪徒 提交于 2020-01-01 03:05:14

问题


I am using Ruby 1.9.2 and the Ruby on Rails v3.2.2 gem. I would like to "nest" the inclusion of modules given I am using the RoR ActiveSupport::Concern feature, but I have a doubt where I should state the include method. That is, I have the following:

module MyModuleA
  extend ActiveSupport::Concern

  # include MyModuleB

  included do
    # include MyModuleB
  end
end

Should I state include MyModuleB in the "body" / "context" / "scope" of MyModuleA or I should state that in the included do ... end block? What is the difference and what I should expect from that?


回答1:


If you include MyModuleB in the "body" of MyModuleA, then it is the module itself that is extended with B's functionality. If you include it in the included block, then it is included on the class that mixes in MyModuleA.

That is:

module MyModuleA
  extend ActiveSupport::Concern
  include MyModuleB
end

produces something like:

MyModuleA.send :include, MyModuleB
class Foo
  include MyModuleA
end

while

module MyModuleA
  extend ActiveSupport::Concern
  included do
    include MyModuleB
  end
end

produces something like:

class Foo
  include MyModuleA
  include MyModuleB
end

The reason for this is that ActiveSupport::Concern::included is analogous to:

def MyModuleA
  def self.included(klass, &block)
    klass.instance_eval(&block)
  end
end

The code in the included block is run in the context of the including class, rather than the context of the module. Thus, if MyModuleB needs access to the class it's being mixed-in to, then you'd want to run it in the included block. Otherwise, it's effectively the same thing.

By means of demonstration:

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


来源:https://stackoverflow.com/questions/13110306/how-to-nest-the-inclusion-of-modules-when-using-the-ruby-on-rails-activesuppor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!