我正在使用
Ruby 1.9.2和
Ruby on Rails v3.2.2 gem.我想使用RoR
ActiveSupport::Concern功能“嵌套”包含模块,但我怀疑应该在哪里说明include方法.也就是说,我有以下几点:
module MyModuleA extend ActiveSupport::Concern # include MyModuleB included do # include MyModuleB end end
我应该在MyModuleA的“body”/“context”/“scope”中声明包含MyModuleB,还是应该在包含的do … end块中声明?有什么区别,我应该从中得到什么?
解决方法
如果在MyModuleA的“主体”中包含MyModuleB,那么模块本身就是用B的功能扩展的.如果将其包含在包含的块中,则它将包含在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需要访问它所混入的类,那么你需要在包含的块中运行它.否则,它实际上是一样的.
通过演示:
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