Permalink
Browse files

Moving more initializers into the application object

  • Loading branch information...
1 parent 6d6ae08 commit e4d7e5090c928e5b64350be9a1fb3aaf6f968e4c Carl Lerche committed Oct 8, 2009
@@ -2,34 +2,39 @@ module Rails
class Application
extend Initializable
- def self.inherited(child)
- child.initializers = initializers.dup
- end
+ class << self
+ def config
+ @config ||= Configuration.new
+ end
- def self.config
- @config ||= Configuration.new
- end
+ # TODO: change the plugin loader to use config
+ alias configuration config
- def self.config=(config)
- @config = config
- end
+ def config=(config)
+ @config = config
+ end
- def self.routes
- ActionController::Routing::Routes
- end
+ def plugin_loader
+ @plugin_loader ||= config.plugin_loader.new(self)
+ end
- def self.middleware
- config.middleware
- end
+ def routes
+ ActionController::Routing::Routes
+ end
- def self.call(env)
- @app ||= middleware.build(routes)
- @app.call(env)
- end
+ def middleware
+ config.middleware
+ end
+
+ def call(env)
+ @app ||= middleware.build(routes)
+ @app.call(env)
+ end
- def self.new
- initializers.run
- self
+ def new
+ initializers.run
+ self
+ end
end
initializer :initialize_rails do
@@ -49,5 +54,49 @@ def self.new
abort %{Your config/boot.rb is outdated: Run "rake rails:update".}
end
end
+
+ # Requires all frameworks specified by the Configuration#frameworks
+ # list. By default, all frameworks (Active Record, Active Support,
+ # Action Pack, Action Mailer, and Active Resource) are loaded.
+ initializer :require_frameworks do
+ begin
+ require 'active_support'
+ require 'active_support/core_ext/kernel/reporting'
+ require 'active_support/core_ext/logger'
+
+ # TODO: This is here to make Sam Ruby's tests pass. Needs discussion.
+ require 'active_support/core_ext/numeric/bytes'
+ config.frameworks.each { |framework| require(framework.to_s) }
+ rescue LoadError => e
+ # Re-raise as RuntimeError because Mongrel would swallow LoadError.
+ raise e.to_s
+ end
+ end
+
+ # Set the paths from which Rails will automatically load source files, and
+ # the load_once paths.
+ initializer :set_autoload_paths do
+ require 'active_support/dependencies'
+ ActiveSupport::Dependencies.load_paths = config.load_paths.uniq
+ ActiveSupport::Dependencies.load_once_paths = config.load_once_paths.uniq
+
+ extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
+ unless extra.empty?
+ abort <<-end_error
+ load_once_paths must be a subset of the load_paths.
+ Extra items in load_once_paths: #{extra * ','}
+ end_error
+ end
+
+ # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
+ config.load_once_paths.freeze
+ end
+
+ # Adds all load paths from plugins to the global set of load paths, so that
+ # code from plugins can be required (explicitly or automatically via ActiveSupport::Dependencies).
+ initializer :add_plugin_load_paths do
+ require 'active_support/dependencies'
+ plugin_loader.add_plugin_load_paths
+ end
end
end
@@ -2,20 +2,58 @@ module Rails
module Initializable
# A collection of initializers
- class Collection < ActiveSupport::OrderedHash
- # def initialize_copy(other)
- # super
- # each do |key, value|
- # self[key] = value.dup
- # end
- # end
+ class Collection
+ def initialize(context)
+ @context = context
+ @keys = []
+ @values = {}
+ @ran = false
+ end
def run
+ return self if @ran
each do |key, initializer|
- initializer.run
+ @context.class_eval(&initializer.block)
end
+ @ran = true
self
end
+
+ def [](key)
+ keys, values = merge_with_parent
+ values[key.to_sym]
+ end
+
+ def []=(key, value)
+ key = key.to_sym
+ @keys |= [key]
+ @values[key] = value
+ end
+
+ def each
+ keys, values = merge_with_parent
+ keys.each { |k| yield k, values[k] }
+ self
+ end
+
+ protected
+
+ attr_reader :keys, :values
+
+ private
+
+ def merge_with_parent
+ keys, values = [], {}
+
+ if @context.is_a?(Class) && @context.superclass.is_a?(Initializable)
+ parent = @context.superclass.initializers
+ keys, values = parent.keys, parent.values
+ end
+
+ values = values.merge(@values)
+ return keys | @keys, values
+ end
+
end
class Initializer
@@ -24,24 +62,15 @@ class Initializer
def initialize(name, options = {}, &block)
@name, @options, @block = name, options, block
end
-
- def run
- return if @already_ran
- @block.call
- @already_ran = true
- end
end
def initializer(name, options = {}, &block)
- initializers[name] = Initializer.new(name, options, &block)
+ @initializers ||= Collection.new(self)
+ @initializers[name] = Initializer.new(name, options, &block)
end
def initializers
- @initializers ||= Collection.new
- end
-
- def initializers=(initializers)
- @initializers = initializers
+ @initializers ||= Collection.new(self)
end
end
@@ -1,6 +1,5 @@
require "pathname"
-require 'active_support/ordered_hash'
require 'rails/initializable'
require 'rails/application'
require 'rails/railties_path'
@@ -117,50 +116,6 @@ def self.run(initializer = nil, config = nil)
end
end
- # Requires all frameworks specified by the Configuration#frameworks
- # list. By default, all frameworks (Active Record, Active Support,
- # Action Pack, Action Mailer, and Active Resource) are loaded.
- Initializer.default.add :require_frameworks do
- begin
- require 'active_support'
- require 'active_support/core_ext/kernel/reporting'
- require 'active_support/core_ext/logger'
-
- # TODO: This is here to make Sam Ruby's tests pass. Needs discussion.
- require 'active_support/core_ext/numeric/bytes'
- configuration.frameworks.each { |framework| require(framework.to_s) }
- rescue LoadError => e
- # Re-raise as RuntimeError because Mongrel would swallow LoadError.
- raise e.to_s
- end
- end
-
- # Set the paths from which Rails will automatically load source files, and
- # the load_once paths.
- Initializer.default.add :set_autoload_paths do
- require 'active_support/dependencies'
- ActiveSupport::Dependencies.load_paths = configuration.load_paths.uniq
- ActiveSupport::Dependencies.load_once_paths = configuration.load_once_paths.uniq
-
- extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
- unless extra.empty?
- abort <<-end_error
- load_once_paths must be a subset of the load_paths.
- Extra items in load_once_paths: #{extra * ','}
- end_error
- end
-
- # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
- configuration.load_once_paths.freeze
- end
-
- # Adds all load paths from plugins to the global set of load paths, so that
- # code from plugins can be required (explicitly or automatically via ActiveSupport::Dependencies).
- Initializer.default.add :add_plugin_load_paths do
- require 'active_support/dependencies'
- plugin_loader.add_plugin_load_paths
- end
-
# Create tmp directories
Initializer.default.add :ensure_tmp_directories_exist do
%w(cache pids sessions sockets).each do |dir_to_make|
@@ -373,7 +328,7 @@ def self.run(initializer = nil, config = nil)
Initializer.default.add :initialize_metal do
# TODO: Make Rails and metal work without ActionController
- if defined?(ActionController)
+ if configuration.frameworks.include?(:action_controller)
Rails::Rack::Metal.requested_metals = configuration.metals
Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
@@ -1,26 +0,0 @@
-require "isolation/abstract_unit"
-
-module ApplicationTests
- class InitializerTest < Test::Unit::TestCase
- include ActiveSupport::Testing::Isolation
-
- def setup
- build_app
- boot_rails
- end
-
- test "initializers only ever run once" do
- class MyApp < Rails::Application
- initializer :counter do
- $counter += 1
- end
- end
-
- $counter = 0
- MyApp.initializers[:counter].run
- MyApp.initializers[:counter].run
-
- assert_equal 1, $counter
- end
- end
-end
@@ -29,5 +29,30 @@ class MyApp < Rails::Application ; end
MyApp.new
assert $:.include?("#{app_path}/app/models")
end
+
+ test "adding an unknown framework raises an error" do
+ class MyApp < Rails::Application
+ config.frameworks << :action_foo
+ end
+
+ assert_raises RuntimeError do
+ MyApp.new
+ end
+ end
+
+ test "eager loading loads parent classes before children" do
+ app_file "lib/zoo.rb", <<-ZOO
+ class Zoo ; include ReptileHouse ; end
+ ZOO
+ app_file "lib/zoo/reptile_house.rb", <<-ZOO
+ module Zoo::ReptileHouse ; end
+ ZOO
+
+ Rails::Initializer.run do |config|
+ config.eager_load_paths = "#{app_path}/lib"
+ end
+
+ assert Zoo
+ end
end
end
Oops, something went wrong.

0 comments on commit e4d7e50

Please sign in to comment.