为什么Rails :: Application有许多重复的初始值设定项,它们在Rails :: Engine中定义?

时间:2013-03-20 09:06:31

标签: ruby-on-rails ruby-on-rails-3 initialization railtie

当我在rails 3初始化过程中工作时,我发现Rails :: Engine(有10个)中定义的所有初始化器都被多次添加到Rails :: Application实例中。这意味着这些初始化程序将运行多次。以下是分析: 1. Rails :: Application#initializers:

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#initializers看到每个引擎(继承自Rails :: Engine的类)都会将Rails :: Engine的初始化器添加到其中,包括Rails :: Application。但是所有其他引擎都包含在Rails :: Application的ordered_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中的每个初始化程序都是Rails :: Application的5倍。我想知道为什么会这样?有什么特别的原因吗?

1 个答案:

答案 0 :(得分:0)

初始化程序除了name之外还有其他几个属性:context,block等。因此,无论何时从Rails :: Engine继承引擎,所有Rails :: Engine的初始化程序都会添加到具有不同上下文的子引擎中。也就是说,虽然Rails :: Application中有相同名称的重复初始化器,但它们确实是不同的初始化器,它们将在不同的上下文中运行:

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