2012-10-28 52 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

相關問題