aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails/initializable.rb
diff options
context:
space:
mode:
Diffstat (limited to 'railties/lib/rails/initializable.rb')
-rw-r--r--railties/lib/rails/initializable.rb134
1 files changed, 83 insertions, 51 deletions
diff --git a/railties/lib/rails/initializable.rb b/railties/lib/rails/initializable.rb
index 4bd5088207..3866b856b2 100644
--- a/railties/lib/rails/initializable.rb
+++ b/railties/lib/rails/initializable.rb
@@ -1,85 +1,117 @@
module Rails
module Initializable
+ def self.included(base)
+ base.extend ClassMethods
+ end
- # A collection of initializers
- class Collection
- def initialize(context)
- @context = context
- @keys = []
- @values = {}
- @ran = false
- end
+ class Initializer
+ attr_reader :name, :before, :after, :global, :block
- def run
- return self if @ran
- each do |key, initializer|
- @context.class_eval(&initializer.block)
- end
- @ran = true
- self
+ def initialize(name, context, options, &block)
+ @name, @context, @options, @block = name, context, options, block
end
- def [](key)
- keys, values = merge_with_parent
- values[key.to_sym]
+ def before
+ @options[:before]
end
- def []=(key, value)
- key = key.to_sym
- @keys |= [key]
- @values[key] = value
+ def after
+ @options[:after]
end
- def each
- keys, values = merge_with_parent
- keys.each { |k| yield k, values[k] }
- self
+ def global
+ @options[:global]
end
- protected
-
- attr_reader :keys, :values
+ alias global? global
- private
+ def run(*args)
+ @context.instance_exec(*args, &block)
+ end
- def merge_with_parent
- keys, values = [], {}
+ def bind(context)
+ return self if @context
+ Initializer.new(@name, context, @options, &block)
+ end
+ end
- if @context.is_a?(Class) && @context.superclass.is_a?(Initializable)
- parent = @context.superclass.initializers
- keys, values = parent.keys, parent.values
+ class Collection < Array
+ def initialize(initializers = [])
+ super()
+ initializers.each do |initializer|
+ if initializer.before
+ index = index_for(initializer.before)
+ elsif initializer.after
+ index = index_for(initializer.after)
+ index += 1 if index
+ else
+ index = length
+ end
+ insert(index || -1, initializer)
end
-
- values = values.merge(@values)
- return keys | @keys, values
end
- end
-
- class Initializer
- attr_reader :name, :options, :block
+ def +(other)
+ Collection.new(to_a + other.to_a)
+ end
- def initialize(name, options = {}, &block)
- @name, @options, @block = name, options, block
+ def index_for(name)
+ initializer = find { |i| i.name == name }
+ initializer && index(initializer)
end
end
- def initializer(name, options = {}, &block)
- @initializers ||= Collection.new(self)
- @initializers[name] = Initializer.new(name, options, &block)
+ def run_initializers(*args)
+ return if @ran
+ initializers.each do |initializer|
+ initializer.run(*args)
+ end
+ @ran = true
end
def initializers
- @initializers ||= Collection.new(self)
+ @initializers ||= begin
+ initializers = self.class.initializers_for(:instance)
+ Collection.new(initializers.map { |i| i.bind(self) })
+ end
end
+ module ClassMethods
+ def initializers
+ @initializers ||= []
+ end
+
+ 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
+
+ def initializer(name, opts = {}, &blk)
+ @initializers ||= []
+ @initializers << Initializer.new(name, nil, opts, &blk)
+ end
+
+ 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
@@ -89,7 +121,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