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

2024-05-02

我正在使用 Ruby 1.9.2 和 Ruby on Rails v3.2.2 gem。鉴于我正在使用 RoR,我想“嵌套”包含模块ActiveSupport::关注 http://api.rubyonrails.org/classes/ActiveSupport/Concern.html功能,但我不确定我应该在哪里声明include方法。也就是说,我有以下内容:

module MyModuleA
  extend ActiveSupport::Concern

  # include MyModuleB

  included do
    # include MyModuleB
  end
end

Should我声明include MyModuleB在“主体”/“上下文”/“范围”中MyModuleA或者我应该指出included do ... end block? 有什么区别以及我应该从中期待什么?


如果你包括MyModuleB在“身体”中MyModuleA,那么模块本身就扩展了 B 的功能。如果您将其包含在included块,然后将其包含在混合的类中MyModuleA.

That is:

module MyModuleA
  extend ActiveSupport::Concern
  include MyModuleB
end

产生类似的东西:

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

while

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

产生类似的东西:

class Foo
  include MyModuleA
  include MyModuleB
end

这样做的原因是ActiveSupport::Concern::included类似于:

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

中的代码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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Ruby on Rails ActiveSupport::Concern 功能时如何“嵌​​套”包含模块? 的相关文章

随机推荐