如何“筑巢”在使用Ruby on Rails ActiveSupport :: Concern功能时包含模块? [英] How to "nest" the inclusion of modules when using the Ruby on Rails ActiveSupport::Concern feature?

查看:398
本文介绍了如何“筑巢”在使用Ruby on Rails ActiveSupport :: Concern功能时包含模块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

应该我在包含MyModuleB code> MyModuleA 或者我应该在中包含do ... 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?

推荐答案

如果包含 MyModuleB MyModuleA 的正文中,然后是使用B功能扩展的模块本身。如果您将其包含在包含的块中,那么它将包含在混合在 MyModuleA 中的类中。

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.

即:

module MyModuleA
  extend ActiveSupport::Concern
  include MyModuleB
end

产生如下内容:

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

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

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

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.

通过演示:

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

这篇关于如何“筑巢”在使用Ruby on Rails ActiveSupport :: Concern功能时包含模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆