Как «вложить» включение модулей при использовании функции ActiveSupport :: Concern Ruby on Rails?

Я использую Ruby 1.9.2 и гем Ruby on Rails v3.2.2. Я бы хотел "гнездо" включение модулей с учетом Я использую RoRActiveSupport :: Концерн особенность, но у меня есть сомнения, где я должен заявитьinclude метод. То есть у меня есть следующее:

module MyModuleA
  extend ActiveSupport::Concern

  # include MyModuleB

  included do
    # include MyModuleB
  end
end

Должен Я заявляюinclude MyModuleB в "тело "/"контекст "/"объем" изMyModuleA или я должен заявить, что вincluded do ... end блок?Какая разница и чего мне от этого ожидать?

 geekazoid09 мар. 2015 г., 22:28
Помните, что это не очень хорошая практика. Вы можете попасть в ложные зависимости между порядком включения модулей.

Ответы на вопрос(1)

Решение Вопроса

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
 Backo28 окт. 2012 г., 17:34
Спасибо. Я открылновый связанный вопрос по методам.

Ваш ответ на вопрос