2012-10-28 46 views
6

我使用Ruby 1.9.2和Ruby on Rails v3.2.2 gem。由于我使用RoR ActiveSupport::Concern功能,因此我想“嵌套”包含的模块,但是我不确定在哪里陈述include方法。也就是说,我有以下几点:如何在使用Ruby on Rails ActiveSupport :: Concern特性时“嵌套”模块的包含?

module MyModuleA 
    extend ActiveSupport::Concern 

    # include MyModuleB 

    included do 
    # include MyModuleB 
    end 
end 

应该我的“身体”状态include MyModuleB /“背景”的MyModuleA /“范围”或者我应该指出,在included do ... end块? 有什么区别,我应该期待什么?

+0

要注意的是,这不是一个很好的做法都没有。您可能会陷入包含模块的顺序之间的虚假依赖关系。 – geekazoid

回答

16

如果您在MyModuleA的“正文”中包含MyModuleB,那么它是模块本身可以用B的功能进行扩展。如果将它包含在included块中,则它将包含在混合在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 

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 
+0

谢谢。我打开了一个[新的相关问题](http://stackoverflow.com/questions/13110749/how-to-make-methods-added-by-the-inclusion-of-a-nested-module-to-be-instance )在方法上。 – Backo

相关问题