7

私はRuby1.9.2とRubyonRailsv3.2.2gemを使用しています。RoR ActiveSupport :: Concern機能を使用している場合、モジュールの包含を「ネスト」したいのですが、メソッドをどこに記載すべきか疑問がありincludeます。つまり、私は次のものを持っています:

module MyModuleA
  extend ActiveSupport::Concern

  # include MyModuleB

  included do
    # include MyModuleB
  end
end

include MyModuleBの「本体」/「コンテキスト」/「スコープ」に記載する必要がありますか、それともブロックMyModuleAに記載する必要がありますか違いは何ですか、そして私はそれから何を期待すべきですか?included do ... end

4

1 に答える 1

22

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
于 2012-10-28T16:06:49.697 に答える