aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
authorwycats <wycats@gmail.com>2010-03-07 06:24:30 -0800
committerwycats <wycats@gmail.com>2010-03-07 06:24:30 -0800
commit39d6f9e112f2320d8c2006ee3bcc160cfa761d0a (patch)
tree5c3e4434a5d76ceb7b8fd088d62809ef9a50f025 /activesupport/lib
parenta424f199a9143e7ea451ba6f5e7dc54eb6103988 (diff)
downloadrails-39d6f9e112f2320d8c2006ee3bcc160cfa761d0a.tar.gz
rails-39d6f9e112f2320d8c2006ee3bcc160cfa761d0a.tar.bz2
rails-39d6f9e112f2320d8c2006ee3bcc160cfa761d0a.zip
Make many parts of Rails lazy. In order to facilitate this,
add lazy_load_hooks.rb, which allows us to declare code that should be run at some later time. For instance, this allows us to defer requiring ActiveRecord::Base at boot time purely to apply configuration. Instead, we register a hook that should apply configuration once ActiveRecord::Base is loaded. With these changes, brings down total boot time of a new app to 300ms in production and 400ms in dev. TODO: rename base_hook
Diffstat (limited to 'activesupport/lib')
-rw-r--r--activesupport/lib/active_support.rb3
-rw-r--r--activesupport/lib/active_support/all.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/array/conversions.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/string/interpolation.rb92
-rw-r--r--activesupport/lib/active_support/dependencies/autoload.rb5
-rw-r--r--activesupport/lib/active_support/i18n.rb3
-rw-r--r--activesupport/lib/active_support/lazy_load_hooks.rb25
-rw-r--r--activesupport/lib/active_support/railtie.rb8
-rw-r--r--activesupport/lib/active_support/whiny_nil.rb7
9 files changed, 44 insertions, 101 deletions
diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb
index ae31d191c0..e34e46b4cf 100644
--- a/activesupport/lib/active_support.rb
+++ b/activesupport/lib/active_support.rb
@@ -53,6 +53,7 @@ module ActiveSupport
autoload :Deprecation
autoload :Gzip
autoload :Inflector
+ autoload :JSON
autoload :Memoizable
autoload :MessageEncryptor
autoload :MessageVerifier
@@ -70,3 +71,5 @@ module ActiveSupport
autoload :SafeBuffer, "active_support/core_ext/string/output_safety"
autoload :TestCase
end
+
+autoload :I18n, "active_support/i18n"
diff --git a/activesupport/lib/active_support/all.rb b/activesupport/lib/active_support/all.rb
index 64600575d9..f537818300 100644
--- a/activesupport/lib/active_support/all.rb
+++ b/activesupport/lib/active_support/all.rb
@@ -1,4 +1,3 @@
require 'active_support'
-require 'active_support/i18n'
require 'active_support/time'
require 'active_support/core_ext'
diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb
index 814567a5a6..2119322bfe 100644
--- a/activesupport/lib/active_support/core_ext/array/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/array/conversions.rb
@@ -1,7 +1,6 @@
require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/inflector'
-require 'active_support/i18n'
class Array
# Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:
diff --git a/activesupport/lib/active_support/core_ext/string/interpolation.rb b/activesupport/lib/active_support/core_ext/string/interpolation.rb
index 06d3505c60..932117cc10 100644
--- a/activesupport/lib/active_support/core_ext/string/interpolation.rb
+++ b/activesupport/lib/active_support/core_ext/string/interpolation.rb
@@ -1,91 +1 @@
-=begin
- heavily based on Masao Mutoh's gettext String interpolation extension
- http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
- Copyright (C) 2005-2010 Masao Mutoh
- You may redistribute it and/or modify it under the same license terms as Ruby.
-=end
-
-if RUBY_VERSION < '1.9' && !"".respond_to?(:interpolate_without_ruby_19_syntax)
-
- # KeyError is raised by String#% when the string contains a named placeholder
- # that is not contained in the given arguments hash. Ruby 1.9 includes and
- # raises this exception natively. We define it to mimic Ruby 1.9's behaviour
- # in Ruby 1.8.x
-
- class KeyError < IndexError
- def initialize(message = nil)
- super(message || "key not found")
- end
- end unless defined?(KeyError)
-
- # Extension for String class. This feature is included in Ruby 1.9 or later but not occur TypeError.
- #
- # String#% method which accept "named argument". The translator can know
- # the meaning of the msgids using "named argument" instead of %s/%d style.
-
- class String
- alias :interpolate_without_ruby_19_syntax :% # :nodoc:
-
- INTERPOLATION_PATTERN = Regexp.union(
- /%%/,
- /%\{(\w+)\}/, # matches placeholders like "%{foo}"
- /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
- )
-
- # % uses self (i.e. the String) as a format specification and returns the
- # result of applying it to the given arguments. In other words it interpolates
- # the given arguments to the string according to the formats the string
- # defines.
- #
- # There are three ways to use it:
- #
- # * Using a single argument or Array of arguments.
- #
- # This is the default behaviour of the String class. See Kernel#sprintf for
- # more details about the format string.
- #
- # Example:
- #
- # "%d %s" % [1, "message"]
- # # => "1 message"
- #
- # * Using a Hash as an argument and unformatted, named placeholders.
- #
- # When you pass a Hash as an argument and specify placeholders with %{foo}
- # it will interpret the hash values as named arguments.
- #
- # Example:
- #
- # "%{firstname}, %{lastname}" % {:firstname => "Masao", :lastname => "Mutoh"}
- # # => "Masao Mutoh"
- #
- # * Using a Hash as an argument and formatted, named placeholders.
- #
- # When you pass a Hash as an argument and specify placeholders with %<foo>d
- # it will interpret the hash values as named arguments and format the value
- # according to the formatting instruction appended to the closing >.
- #
- # Example:
- #
- # "%<integer>d, %<float>.1f" % { :integer => 10, :float => 43.4 }
- # # => "10, 43.3"
- def %(args)
- if args.kind_of?(Hash)
- dup.gsub(INTERPOLATION_PATTERN) do |match|
- if match == '%%'
- '%'
- else
- key = ($1 || $2).to_sym
- raise KeyError unless args.has_key?(key)
- $3 ? sprintf("%#{$3}", args[key]) : args[key]
- end
- end
- elsif self =~ INTERPOLATION_PATTERN
- raise ArgumentError.new('one hash required')
- else
- result = gsub(/%([{<])/, '%%\1')
- result.send :'interpolate_without_ruby_19_syntax', args
- end
- end
- end
-end
+require 'i18n/core_ext/string/interpolate'
diff --git a/activesupport/lib/active_support/dependencies/autoload.rb b/activesupport/lib/active_support/dependencies/autoload.rb
index 44edb89ad5..f669f4a77e 100644
--- a/activesupport/lib/active_support/dependencies/autoload.rb
+++ b/activesupport/lib/active_support/dependencies/autoload.rb
@@ -1,7 +1,12 @@
require "active_support/inflector/methods"
+require "active_support/lazy_load_hooks"
module ActiveSupport
module Autoload
+ def self.extended(base)
+ base.extend(LazyLoadHooks)
+ end
+
@@autoloads = {}
@@under_path = nil
@@at_path = nil
diff --git a/activesupport/lib/active_support/i18n.rb b/activesupport/lib/active_support/i18n.rb
index 854c60eec1..034d7d8ddc 100644
--- a/activesupport/lib/active_support/i18n.rb
+++ b/activesupport/lib/active_support/i18n.rb
@@ -1,2 +1,3 @@
require 'i18n'
-I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml" \ No newline at end of file
+I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
+ActiveSupport.run_base_hooks(:i18n) \ No newline at end of file
diff --git a/activesupport/lib/active_support/lazy_load_hooks.rb b/activesupport/lib/active_support/lazy_load_hooks.rb
new file mode 100644
index 0000000000..36acfda524
--- /dev/null
+++ b/activesupport/lib/active_support/lazy_load_hooks.rb
@@ -0,0 +1,25 @@
+module ActiveSupport
+ module LazyLoadHooks
+ def _setup_base_hooks
+ @base_hooks ||= Hash.new {|h,k| h[k] = [] }
+ @base ||= {}
+ end
+
+ def base_hook(name = nil, &block)
+ _setup_base_hooks
+
+ if base = @base[name]
+ base.instance_eval(&block)
+ else
+ @base_hooks[name] << block
+ end
+ end
+
+ def run_base_hooks(base, name = nil)
+ _setup_base_hooks
+
+ @base_hooks[name].each { |hook| base.instance_eval(&hook) } if @base_hooks
+ @base[name] = base
+ end
+ end
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/railtie.rb b/activesupport/lib/active_support/railtie.rb
index 58d11585ba..d2c13e030d 100644
--- a/activesupport/lib/active_support/railtie.rb
+++ b/activesupport/lib/active_support/railtie.rb
@@ -37,10 +37,12 @@ module I18n
config.i18n.load_path = []
initializer "i18n.initialize" do
- require 'active_support/i18n'
-
- ActionDispatch::Callbacks.to_prepare do
+ ActiveSupport.base_hook(:i18n) do
I18n.reload!
+
+ ActionDispatch::Callbacks.to_prepare do
+ I18n.reload!
+ end
end
end
diff --git a/activesupport/lib/active_support/whiny_nil.rb b/activesupport/lib/active_support/whiny_nil.rb
index 0b68e936f6..91ddef2619 100644
--- a/activesupport/lib/active_support/whiny_nil.rb
+++ b/activesupport/lib/active_support/whiny_nil.rb
@@ -25,17 +25,16 @@
# By default it is on in development and test modes, and it is off in production
# mode.
class NilClass
- WHINERS = [::Array]
- WHINERS << ::ActiveRecord::Base if defined? ::ActiveRecord::Base
-
METHOD_CLASS_MAP = Hash.new
- WHINERS.each do |klass|
+ def self.add_whiner(klass)
methods = klass.public_instance_methods - public_instance_methods
class_name = klass.name
methods.each { |method| METHOD_CLASS_MAP[method.to_sym] = class_name }
end
+ add_whiner ::Array
+
# Raises a RuntimeError when you attempt to call +id+ on +nil+.
def id
raise RuntimeError, "Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id", caller