Почему в Rails::Application есть много повторяющихся инициализаторов, которые определены в Rails::Engine?
Работая в процессе инициализации rails 3, я обнаружил, что все инициализаторы, определенные в Rails::Engine(их 10), были добавлены в экземпляр Rails::Application более одного раза. Это означает, что эти инициализаторы будут выполняться много раз. Ниже приведен анализ: 1. Rails::Application#initializer:
def initializers #:nodoc:
Bootstrap.initializers_for(self) +
super +
Finisher.initializers_for(self)
end
Он вызовет метод super(Rails::Engine), который определен следующим образом:
def initializers
initializers = []
ordered_railties.each do |r|
if r == self
initializers += super
else
initializers += r.initializers
end
end
initializers
end
Из инициализаторов Rails:: Engine # видно, что каждый движок (класс, унаследованный от Rails:: Engine) будет добавлять к нему инициализаторы Rails:: Engine, включая Rails::Application. Но все остальные движки включены в Rails::Application order_railties, поэтому их инициализаторы также добавляются в Rails::Application. Мы можем заключить, что инициализаторы Rails:: Engine добавляются много раз в Rails::Application. Мы можем увидеть из консоли информацию:
1.9.3p194 :002 > Rails.application.initializers.map(&:name).size
=> 119
1.9.3p194 :001 > Rails.application.initializers.map(&:name).uniq.size
=> 79
Таким образом, каждый инициализатор в Rails:: Engine добавляется 5 раз в Rails::Application. Интересно, почему это происходит? Есть ли какая-то особая причина?
1 ответ
Инициализатор имеет несколько других атрибутов, кроме name: context, block и т. Д. Поэтому всякий раз, когда движок, унаследованный от Rails:: Engine, все инициализаторы Rails:: Engine добавляются в дочерний движок с другим контекстом. То есть, хотя в Rails::Application есть повторяющиеся инициализаторы с одинаковыми именами, они действительно являются разными инициализаторами, которые будут работать в другом контексте:
def run(*args)
@context.instance_exec(*args, &block)
end