MyModuleB
の「本体」に含める場合MyModuleA
、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