aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--railties/lib/rails/application.rb45
-rw-r--r--railties/lib/rails/initializable.rb111
-rw-r--r--railties/lib/rails/plugin.rb99
-rw-r--r--railties/test/initializable_test.rb72
4 files changed, 192 insertions, 135 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 242aea1842..b43dcb0041 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -1,6 +1,6 @@
module Rails
class Application
- extend Initializable
+ include Initializable
class << self
# Stub out App initialize
@@ -8,6 +8,10 @@ module Rails
new
end
+ def new
+ @instance ||= super
+ end
+
def config
@config ||= Configuration.new
end
@@ -27,23 +31,36 @@ module Rails
config.root
end
- def routes
- ActionController::Routing::Routes
+ def call(env)
+ new.call(env)
end
+ end
- def middleware
- config.middleware
- end
+ def initialize
+ run_initializers
+ end
- def call(env)
- @app ||= middleware.build(routes)
- @app.call(env)
- end
+ def config
+ self.class.config
+ end
- def new
- run_initializers
- self
- end
+ alias configuration config
+
+ def plugin_loader
+ self.class.plugin_loader
+ end
+
+ def middleware
+ config.middleware
+ end
+
+ def routes
+ ActionController::Routing::Routes
+ end
+
+ def call(env)
+ @app ||= middleware.build(routes)
+ @app.call(env)
end
initializer :initialize_rails do
diff --git a/railties/lib/rails/initializable.rb b/railties/lib/rails/initializable.rb
index c491d5e012..93349454dd 100644
--- a/railties/lib/rails/initializable.rb
+++ b/railties/lib/rails/initializable.rb
@@ -1,93 +1,82 @@
module Rails
module Initializable
- def self.included(klass)
- klass.instance_eval do
- extend Rails::Initializable
- extend Rails::Initializable::ClassMethodsWhenIncluded
- include Rails::Initializable::InstanceMethodsWhenIncluded
- end
+ def self.included(base)
+ base.extend ClassMethods
end
- def self.extended(klass)
- klass.extend Initializer
+ Initializer = Struct.new(:name, :before, :after, :global, :block) do
+ alias global? global
end
class Collection < Array
- def initialize(klasses)
- klasses.each do |klass|
- (klass.added_initializers || []).each do |initializer|
- index = if initializer.before
- index_for(initializer.before)
- elsif initializer.after
- index_for(initializer.after) + 1
- else
- length
- end
-
- insert(index, initializer)
+ def initialize(initializers = [])
+ super()
+ initializers.each do |initializer|
+ if initializer.before
+ index = index_for(initializer.before)
+ elsif initializer.after
+ index = index_for(initializer.after) + 1
+ else
+ index = length
end
+ insert(index || -1, initializer)
end
end
- def index_for(name)
- inst = find {|i| i.name == name }
- inst && index(inst)
+ def +(other)
+ Collection.new(to_a + other.to_a)
end
+ def index_for(name)
+ initializer = find { |i| i.name == name }
+ initializer && index(initializer)
+ end
end
- attr_reader :added_initializers
-
- # When you include Rails::Initializable, this method will be on instances
- # of the class included into. When you extend it, it will be on the
- # class or module itself.
- #
- # The #initializers method is set up to return the right list of
- # initializers for the context in question.
- def run_initializers
- return if @_initialized
-
- initializers.each {|initializer| instance_eval(&initializer.block) }
-
- @_initialized = true
+ def run_initializers(*args)
+ return if @ran
+ self.class.initializers_for(:instance).each do |initializer|
+ instance_exec(*args, &initializer.block)
+ end
+ @ran = true
end
- module Initializer
- Initializer = Struct.new(:name, :before, :after, :block, :global)
-
- def all_initializers
- klasses = ancestors.select {|klass| klass.is_a?(Initializable) }.reverse
- initializers = Collection.new(klasses)
+ module ClassMethods
+ def initializers
+ @initializers ||= []
end
- alias initializers all_initializers
-
- def initializer(name, options = {}, &block)
- @added_initializers ||= []
- @added_initializers <<
- Initializer.new(name, options[:before], options[:after], block, options[:global])
+ def initializers_for(scope = :global)
+ initializers = Collection.new
+ ancestors.reverse_each do |klass|
+ next unless klass.respond_to?(:initializers)
+ initializers = initializers + klass.initializers.select { |i|
+ (scope == :global) == !!i.global?
+ }
+ end
+ initializers
end
- end
- module ClassMethodsWhenIncluded
- def initializers
- all_initializers.select {|i| i.global == true }
+ def initializer(name, opts = {}, &blk)
+ @initializers ||= []
+ @initializers << Initializer.new(name, opts[:before], opts[:after], opts[:global], blk)
end
- end
-
- module InstanceMethodsWhenIncluded
- def initializers
- self.class.all_initializers.reject {|i| i.global == true }
+ def run_initializers(*args)
+ return if @ran
+ initializers_for(:global).each do |initializer|
+ instance_exec(*args, &initializer.block)
+ end
+ @ran = true
end
end
end
- extend Initializable
+ include Initializable
# Check for valid Ruby version (1.8.2 or 1.8.4 or higher). This is done in an
# external file, so we can use it from the `rails` program as well without duplication.
- initializer :check_ruby_version do
+ initializer :check_ruby_version, :global => true do
require 'rails/ruby_version_check'
end
@@ -97,7 +86,7 @@ module Rails
# on ActionController::Base.
#
# For Ruby 1.9, UTF-8 is the default internal and external encoding.
- initializer :initialize_encoding do
+ initializer :initialize_encoding, :global => true do
if RUBY_VERSION < '1.9'
$KCODE='u'
else
diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb
index 1c0af6411a..090ec6e4cb 100644
--- a/railties/lib/rails/plugin.rb
+++ b/railties/lib/rails/plugin.rb
@@ -18,6 +18,7 @@ module Rails
# plugin.about["url"] # => "http://interblah.net"
class Plugin
include Comparable
+ include Initializable
attr_reader :directory, :name
@@ -99,67 +100,69 @@ module Rails
def locale_files
Dir[ File.join(locale_path, '*.{rb,yml}') ]
end
-
- private
- def load_about_information
- about_yml_path = File.join(@directory, "about.yml")
- parsed_yml = File.exist?(about_yml_path) ? YAML.load(File.read(about_yml_path)) : {}
- parsed_yml || {}
- rescue Exception
- {}
- end
+ private
+ def load_about_information
+ about_yml_path = File.join(@directory, "about.yml")
+ parsed_yml = File.exist?(about_yml_path) ? YAML.load(File.read(about_yml_path)) : {}
+ parsed_yml || {}
+ rescue Exception
+ {}
+ end
- def report_nonexistant_or_empty_plugin!
- raise LoadError, "Can not find the plugin named: #{name}"
- end
+ def report_nonexistant_or_empty_plugin!
+ raise LoadError, "Can not find the plugin named: #{name}"
+ end
-
- def app_paths
- [ File.join(directory, 'app', 'models'), File.join(directory, 'app', 'helpers'), controller_path, metal_path ]
- end
-
- def lib_path
- File.join(directory, 'lib')
- end
+ def app_paths
+ [ File.join(directory, 'app', 'models'), File.join(directory, 'app', 'helpers'), controller_path, metal_path ]
+ end
- def classic_init_path
- File.join(directory, 'init.rb')
- end
+ def lib_path
+ File.join(directory, 'lib')
+ end
- def gem_init_path
- File.join(directory, 'rails', 'init.rb')
- end
+ def classic_init_path
+ File.join(directory, 'init.rb')
+ end
- def init_path
- File.file?(gem_init_path) ? gem_init_path : classic_init_path
- end
+ def gem_init_path
+ File.join(directory, 'rails', 'init.rb')
+ end
+ def init_path
+ File.file?(gem_init_path) ? gem_init_path : classic_init_path
+ end
- def has_app_directory?
- File.directory?(File.join(directory, 'app'))
- end
+ def has_app_directory?
+ File.directory?(File.join(directory, 'app'))
+ end
- def has_lib_directory?
- File.directory?(lib_path)
- end
+ def has_lib_directory?
+ File.directory?(lib_path)
+ end
- def has_init_file?
- File.file?(init_path)
- end
+ def has_init_file?
+ File.file?(init_path)
+ end
+ def evaluate_init_rb(initializer)
+ if has_init_file?
+ require 'active_support/core_ext/kernel/reporting'
+ silence_warnings do
+ # Allow plugins to reference the current configuration object
+ config = initializer.configuration
- def evaluate_init_rb(initializer)
- if has_init_file?
- require 'active_support/core_ext/kernel/reporting'
- silence_warnings do
- # Allow plugins to reference the current configuration object
- config = initializer.configuration
-
- eval(IO.read(init_path), binding, init_path)
- end
+ eval(IO.read(init_path), binding, init_path)
end
- end
+ end
+ end
+
+ class Vendored < Plugin
+ initializer :init_rb do |application|
+ evaluate_init_rb(application)
+ end
+ end
end
# This Plugin subclass represents a Gem plugin. Although RubyGems has already
diff --git a/railties/test/initializable_test.rb b/railties/test/initializable_test.rb
index f7237e69cc..463fdc03c0 100644
--- a/railties/test/initializable_test.rb
+++ b/railties/test/initializable_test.rb
@@ -4,59 +4,59 @@ require 'rails/initializable'
module InitializableTests
class Foo
- extend Rails::Initializable
+ include Rails::Initializable
class << self
attr_accessor :foo, :bar
end
- initializer :omg do
+ initializer :omg, :global => true do
@foo ||= 0
@foo += 1
end
end
class Bar < Foo
- initializer :bar do
+ initializer :bar, :global => true do
@bar ||= 0
@bar += 1
end
end
module Word
- extend Rails::Initializable
+ include Rails::Initializable
- initializer :word do
+ initializer :word, :global => true do
$word = "bird"
end
end
class Parent
- extend Rails::Initializable
+ include Rails::Initializable
- initializer :one do
+ initializer :one, :global => true do
$arr << 1
end
- initializer :two do
+ initializer :two, :global => true do
$arr << 2
end
end
class Child < Parent
- extend Rails::Initializable
+ include Rails::Initializable
- initializer :three, :before => :one do
+ initializer :three, :before => :one, :global => true do
$arr << 3
end
- initializer :four, :after => :one do
+ initializer :four, :after => :one, :global => true do
$arr << 4
end
end
class Parent
- initializer :five, :before => :one do
+ initializer :five, :before => :one, :global => true do
$arr << 5
end
end
@@ -81,6 +81,38 @@ module InitializableTests
end
end
+ class WithArgs
+ include Rails::Initializable
+
+ initializer :foo do |arg|
+ $with_arg = arg
+ end
+ end
+
+ class OverriddenInitializer
+ class MoreInitializers
+ include Rails::Initializable
+
+ initializer :startup, :before => :last do
+ $arr << 2
+ end
+ end
+
+ include Rails::Initializable
+
+ initializer :first do
+ $arr << 1
+ end
+
+ initializer :last do
+ $arr << 3
+ end
+
+ def self.initializers
+ super + MoreInitializers.initializers
+ end
+ end
+
class Basic < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
@@ -140,4 +172,20 @@ module InitializableTests
assert_equal [3, 4], $arr
end
end
+
+ class WithArgsTest < ActiveSupport::TestCase
+ test "running initializers with args" do
+ $with_arg = nil
+ WithArgs.new.run_initializers('foo')
+ assert_equal 'foo', $with_arg
+ end
+ end
+
+ class OverriddenInitializerTest < ActiveSupport::TestCase
+ test "merges in the initializers from the parent in the right order" do
+ $arr = []
+ OverriddenInitializer.new.run_initializers
+ assert_equal [1, 2, 3], $arr
+ end
+ end
end \ No newline at end of file