2013-03-20 2 views
1

Как я работал через процесс инициализации рельсов 3, я обнаружил, что все инициализаторы, определенные в Rails :: Engine (их 10), были добавлены в Rails :: Application экземпляр более одного раза. Это означает, что эти инициализаторы будут работать много раз. Ниже приводится анализ: 1. Rails :: Application # Инициализаторы:Почему Rails :: Приложение имеет много повторяющихся инициализаторов, которые определены в Rails :: Engine?

def initializers #:nodoc:   
    Bootstrap.initializers_for(self) + 
    super +       
    Finisher.initializers_for(self) 
end 

Он будет называть супер (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's 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. Интересно, почему это происходит? Есть ли какая-то особая причина?

ответ

0

Инициализатор имеет несколько других атрибутов, кроме имени: контекст, блок и т. Д. Поэтому всякий раз, когда двигатель унаследован от Rails :: Engine, все инициализаторы Rails :: Engine добавляются в дочерний движок с другим контекстом. То есть, хотя в Rails :: Application с тем же именем имеются повторяющиеся инициализаторы, они действительно отличаются инициализаторами, которые будут работать в другом контексте:

def run(*args)       
    @context.instance_exec(*args, &block) 
end