aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib/active_support')
-rw-r--r--activesupport/lib/active_support/basic_object.rb1
-rw-r--r--activesupport/lib/active_support/cache.rb7
-rw-r--r--activesupport/lib/active_support/cache/file_store.rb2
-rw-r--r--activesupport/lib/active_support/cache/mem_cache_store.rb1
-rw-r--r--activesupport/lib/active_support/callbacks.rb111
-rw-r--r--activesupport/lib/active_support/core_ext/class/delegating_attributes.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/date/calculations.rb7
-rw-r--r--activesupport/lib/active_support/core_ext/file/atomic.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/hash/deep_dup.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/hash/slice.rb12
-rw-r--r--activesupport/lib/active_support/core_ext/integer/inflections.rb14
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb16
-rw-r--r--activesupport/lib/active_support/core_ext/object/blank.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/object/duplicable.rb13
-rw-r--r--activesupport/lib/active_support/core_ext/proc.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/range/overlaps.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/string.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb36
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb11
-rw-r--r--activesupport/lib/active_support/dependencies.rb29
-rw-r--r--activesupport/lib/active_support/dependencies/autoload.rb11
-rw-r--r--activesupport/lib/active_support/file_update_checker.rb17
-rw-r--r--activesupport/lib/active_support/gzip.rb1
-rw-r--r--activesupport/lib/active_support/hash_with_indifferent_access.rb13
-rw-r--r--activesupport/lib/active_support/inflections.rb16
-rw-r--r--activesupport/lib/active_support/inflector/inflections.rb15
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb54
-rw-r--r--activesupport/lib/active_support/json/encoding.rb4
-rw-r--r--activesupport/lib/active_support/lazy_load_hooks.rb50
-rw-r--r--activesupport/lib/active_support/log_subscriber.rb8
-rw-r--r--activesupport/lib/active_support/multibyte/unicode.rb2
-rw-r--r--activesupport/lib/active_support/notifications.rb7
-rw-r--r--activesupport/lib/active_support/notifications/fanout.rb103
-rw-r--r--activesupport/lib/active_support/notifications/instrumenter.rb8
-rw-r--r--activesupport/lib/active_support/ordered_options.rb4
-rw-r--r--activesupport/lib/active_support/railtie.rb27
-rw-r--r--activesupport/lib/active_support/rescuable.rb6
-rw-r--r--activesupport/lib/active_support/ruby/shim.rb1
-rw-r--r--activesupport/lib/active_support/tagged_logging.rb6
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb55
-rw-r--r--activesupport/lib/active_support/values/unicode_tables.datbin877274 -> 904408 bytes
-rw-r--r--activesupport/lib/active_support/xml_mini/jdom.rb1
-rw-r--r--activesupport/lib/active_support/xml_mini/libxml.rb1
-rw-r--r--activesupport/lib/active_support/xml_mini/libxmlsax.rb3
-rw-r--r--activesupport/lib/active_support/xml_mini/nokogiri.rb1
-rw-r--r--activesupport/lib/active_support/xml_mini/nokogirisax.rb3
-rw-r--r--activesupport/lib/active_support/xml_mini/rexml.rb1
47 files changed, 374 insertions, 317 deletions
diff --git a/activesupport/lib/active_support/basic_object.rb b/activesupport/lib/active_support/basic_object.rb
index c3c7ab0112..6ccb0cd525 100644
--- a/activesupport/lib/active_support/basic_object.rb
+++ b/activesupport/lib/active_support/basic_object.rb
@@ -10,5 +10,4 @@ module ActiveSupport
::Object.send(:raise, *args)
end
end
-
end
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index 26e737e917..b9f196d7a9 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -91,6 +91,7 @@ module ActiveSupport
case
when key.respond_to?(:cache_key) then key.cache_key
when key.is_a?(Array) then key.map { |element| retrieve_cache_key(element) }.to_param
+ when key.respond_to?(:to_a) then retrieve_cache_key(key.to_a)
else key.to_param
end.to_s
end
@@ -382,11 +383,7 @@ module ActiveSupport
options = merged_options(options)
instrument(:exist?, name) do |payload|
entry = read_entry(namespaced_key(name, options), options)
- if entry && !entry.expired?
- true
- else
- false
- end
+ entry && !entry.expired?
end
end
diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb
index 9460532af0..b7712a4a15 100644
--- a/activesupport/lib/active_support/cache/file_store.rb
+++ b/activesupport/lib/active_support/cache/file_store.rb
@@ -143,7 +143,7 @@ module ActiveSupport
# Translate a file path into a key.
def file_path_key(path)
- fname = path[cache_path.size, path.size].split(File::SEPARATOR, 4).last
+ fname = path[cache_path.to_s.size..-1].split(File::SEPARATOR, 4).last
Rack::Utils.unescape(fname)
end
diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb
index e38a8387b4..2e1ccb72d8 100644
--- a/activesupport/lib/active_support/cache/mem_cache_store.rb
+++ b/activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -6,7 +6,6 @@ rescue LoadError => e
end
require 'digest/md5'
-require 'active_support/core_ext/string/encoding'
module ActiveSupport
module Cache
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 5eaeac2cb3..6e36edee4f 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -66,8 +66,6 @@ module ActiveSupport
#
# Calls the before and around callbacks in the order they were set, yields
# the block (if given one), and then runs the after callbacks in reverse order.
- # Optionally accepts a key, which will be used to compile an optimized callback
- # method for each key. See +ClassMethods.define_callbacks+ for more information.
#
# If the callback chain was halted, returns +false+. Otherwise returns the result
# of the block, or +true+ if no block is given.
@@ -77,7 +75,8 @@ module ActiveSupport
# end
#
def run_callbacks(kind, key = nil, &block)
- self.class.__run_callbacks(key, kind, self, &block)
+ #TODO: deprecate key argument
+ self.class.__run_callbacks(kind, self, &block)
end
private
@@ -95,12 +94,18 @@ module ActiveSupport
def initialize(chain, filter, kind, options, klass)
@chain, @kind, @klass = chain, kind, klass
+ deprecate_per_key_option(options)
normalize_options!(options)
@raw_filter, @options = filter, options
@filter = _compile_filter(filter)
- @compiled_options = _compile_options(options)
- @callback_id = next_id
+ recompile_options!
+ end
+
+ def deprecate_per_key_option(options)
+ if options[:per_key]
+ raise NotImplementedError, ":per_key option is no longer supported. Use generic :if and :unless options instead."
+ end
end
def clone(chain, klass)
@@ -116,11 +121,6 @@ module ActiveSupport
def normalize_options!(options)
options[:if] = Array(options[:if])
options[:unless] = Array(options[:unless])
-
- options[:per_key] ||= {}
-
- options[:if] += Array(options[:per_key][:if])
- options[:unless] += Array(options[:per_key][:unless])
end
def name
@@ -136,21 +136,19 @@ module ActiveSupport
end
def _update_filter(filter_options, new_options)
- filter_options[:if].push(new_options[:unless]) if new_options.key?(:unless)
- filter_options[:unless].push(new_options[:if]) if new_options.key?(:if)
+ filter_options[:if].concat(Array(new_options[:unless])) if new_options.key?(:unless)
+ filter_options[:unless].concat(Array(new_options[:if])) if new_options.key?(:if)
end
- def recompile!(_options, _per_key)
+ def recompile!(_options)
+ deprecate_per_key_option(_options)
_update_filter(self.options, _options)
- _update_filter(self.options, _per_key)
- @callback_id = next_id
- @filter = _compile_filter(@raw_filter)
- @compiled_options = _compile_options(@options)
+ recompile_options!
end
# Wraps code with filter
- def apply(code, key=nil, object=nil)
+ def apply(code)
case @kind
when :before
<<-RUBY_EVAL
@@ -169,7 +167,7 @@ module ActiveSupport
when :after
<<-RUBY_EVAL
#{code}
- if #{@compiled_options}
+ if #{!chain.config[:skip_after_callbacks_if_terminated] || "!halted"} && #{@compiled_options}
#{@filter}
end
RUBY_EVAL
@@ -220,7 +218,7 @@ module ActiveSupport
# Options support the same options as filters themselves (and support
# symbols, string, procs, and objects), so compile a conditional
# expression based on the options
- def _compile_options(options)
+ def recompile_options!
conditions = ["true"]
unless options[:if].empty?
@@ -231,7 +229,7 @@ module ActiveSupport
conditions << Array(_compile_filter(options[:unless])).map {|f| "!#{f}"}
end
- conditions.flatten.join(" && ")
+ @compiled_options = conditions.flatten.join(" && ")
end
# Filters support:
@@ -309,57 +307,37 @@ module ActiveSupport
@name = name
@config = {
:terminator => "false",
- :rescuable => false,
:scope => [ :kind ]
}.merge(config)
end
- def compile(key=nil, object=nil)
+ def compile
method = []
method << "value = nil"
method << "halted = false"
- callbacks = yielding
+ callbacks = "value = yield if block_given? && !halted"
reverse_each do |callback|
- callbacks = callback.apply(callbacks, key, object)
+ callbacks = callback.apply(callbacks)
end
method << callbacks
- method << "raise rescued_error if rescued_error" if config[:rescuable]
method << "halted ? false : (block_given? ? value : true)"
method.flatten.compact.join("\n")
end
- # Returns part of method that evaluates the callback block
- def yielding
- method = []
- if config[:rescuable]
- method << "rescued_error = nil"
- method << "begin"
- end
-
- method << "value = yield if block_given? && !halted"
-
- if config[:rescuable]
- method << "rescue Exception => e"
- method << "rescued_error = e"
- method << "end"
- end
- method.join("\n")
- end
-
end
module ClassMethods
- # This method calls the callback method for the given key.
- # If this called first time it creates a new callback method for the key,
- # calculating which callbacks can be omitted because of per_key conditions.
+ # This method runs callback chain for the given kind.
+ # If this called first time it creates a new callback method for the kind.
+ # This generated method plays caching role.
#
- def __run_callbacks(key, kind, object, &blk) #:nodoc:
+ def __run_callbacks(kind, object, &blk) #:nodoc:
name = __callback_runner_name(kind)
- unless object.respond_to?(name)
- str = object.send("_#{kind}_callbacks").compile(key, object)
+ unless object.respond_to?(name, true)
+ str = object.send("_#{kind}_callbacks").compile
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def #{name}() #{str} end
protected :#{name}
@@ -427,29 +405,6 @@ module ActiveSupport
# will be called only when it returns a false value.
# * <tt>:prepend</tt> - If true, the callback will be prepended to the existing
# chain rather than appended.
- # * <tt>:per_key</tt> - A hash with <tt>:if</tt> and <tt>:unless</tt> options;
- # see "Per-key conditions" below.
- #
- # ===== Per-key conditions
- #
- # When creating or skipping callbacks, you can specify conditions that
- # are always the same for a given key. For instance, in Action Pack,
- # we convert :only and :except conditions into per-key conditions.
- #
- # before_filter :authenticate, :except => "index"
- #
- # becomes
- #
- # set_callback :process_action, :before, :authenticate, :per_key => {:unless => proc {|c| c.action_name == "index"}}
- #
- # Per-key conditions are evaluated only once per use of a given key.
- # In the case of the above example, you would do:
- #
- # run_callbacks(:process_action, action_name) { ... dispatch stuff ... }
- #
- # In that case, each action_name would get its own compiled callback
- # method that took into consideration the per_key conditions. This
- # is a speed improvement for ActionPack.
#
def set_callback(name, *filter_list, &block)
mapped = nil
@@ -484,7 +439,7 @@ module ActiveSupport
if filter && options.any?
new_filter = filter.clone(chain, self)
chain.insert(chain.index(filter), new_filter)
- new_filter.recompile!(options, options[:per_key] || {})
+ new_filter.recompile!(options)
end
chain.delete(filter)
@@ -528,10 +483,10 @@ module ActiveSupport
# other callbacks are not executed. Defaults to "false", meaning no value
# halts the chain.
#
- # * <tt>:rescuable</tt> - By default, after filters are not executed if
- # the given block or a before filter raises an error. By setting this option
- # to <tt>true</tt> exception raised by given block is stored and after
- # executing all the after callbacks the stored exception is raised.
+ # * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after callbacks should be terminated
+ # by the <tt>:terminator</tt> option. By default after callbacks executed no matter
+ # if callback chain was terminated or not.
+ # Option makes sence only when <tt>:terminator</tt> option is specified.
#
# * <tt>:scope</tt> - Indicates which methods should be executed when an object
# is used as a callback.
diff --git a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
index 29bf7c0f3d..0634f20e3c 100644
--- a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
+++ b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
@@ -1,5 +1,3 @@
-require 'active_support/core_ext/object/blank'
-require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/kernel/singleton_class'
require 'active_support/core_ext/module/remove_method'
diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb
index af78226c21..6d4270f8b0 100644
--- a/activesupport/lib/active_support/core_ext/date/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date/calculations.rb
@@ -182,6 +182,13 @@ class Date
result = (self - 7).beginning_of_week + DAYS_INTO_WEEK[day]
self.acts_like?(:time) ? result.change(:hour => 0) : result
end
+ alias :last_week :prev_week
+
+ # Alias of prev_month
+ alias :last_month :prev_month
+
+ # Alias of prev_year
+ alias :last_year :prev_year
# Returns a new Date/DateTime representing the start of the given day in next week (default is :monday).
def next_week(day = :monday)
diff --git a/activesupport/lib/active_support/core_ext/file/atomic.rb b/activesupport/lib/active_support/core_ext/file/atomic.rb
index 3645597301..fc3277f4d2 100644
--- a/activesupport/lib/active_support/core_ext/file/atomic.rb
+++ b/activesupport/lib/active_support/core_ext/file/atomic.rb
@@ -17,6 +17,7 @@ class File
require 'fileutils' unless defined?(FileUtils)
temp_file = Tempfile.new(basename(file_name), temp_dir)
+ temp_file.binmode
yield temp_file
temp_file.close
diff --git a/activesupport/lib/active_support/core_ext/hash/deep_dup.rb b/activesupport/lib/active_support/core_ext/hash/deep_dup.rb
index 447142605c..9ab179c566 100644
--- a/activesupport/lib/active_support/core_ext/hash/deep_dup.rb
+++ b/activesupport/lib/active_support/core_ext/hash/deep_dup.rb
@@ -3,8 +3,7 @@ class Hash
def deep_dup
duplicate = self.dup
duplicate.each_pair do |k,v|
- tv = duplicate[k]
- duplicate[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_dup : v
+ duplicate[k] = v.is_a?(Hash) ? v.deep_dup : v
end
duplicate
end
diff --git a/activesupport/lib/active_support/core_ext/hash/slice.rb b/activesupport/lib/active_support/core_ext/hash/slice.rb
index 0484d8e5d8..45181f0e16 100644
--- a/activesupport/lib/active_support/core_ext/hash/slice.rb
+++ b/activesupport/lib/active_support/core_ext/hash/slice.rb
@@ -13,17 +13,15 @@ class Hash
# valid_keys = [:mass, :velocity, :time]
# search(options.slice(*valid_keys))
def slice(*keys)
- keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
- hash = self.class.new
- keys.each { |k| hash[k] = self[k] if has_key?(k) }
- hash
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
+ keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
end
# Replaces the hash with only the given keys.
# Returns a hash contained the removed key/value pairs
# {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d => 4}
def slice!(*keys)
- keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
omit = slice(*self.keys - keys)
hash = slice(*keys)
replace(hash)
@@ -33,8 +31,6 @@ class Hash
# Removes and returns the key/value pairs matching the given keys.
# {:a => 1, :b => 2, :c => 3, :d => 4}.extract!(:a, :b) # => {:a => 1, :b => 2}
def extract!(*keys)
- result = {}
- keys.each {|key| result[key] = delete(key) }
- result
+ keys.each_with_object({}) {|key, result| result[key] = delete(key) }
end
end
diff --git a/activesupport/lib/active_support/core_ext/integer/inflections.rb b/activesupport/lib/active_support/core_ext/integer/inflections.rb
index 0e606056c0..1e30687166 100644
--- a/activesupport/lib/active_support/core_ext/integer/inflections.rb
+++ b/activesupport/lib/active_support/core_ext/integer/inflections.rb
@@ -14,4 +14,18 @@ class Integer
def ordinalize
ActiveSupport::Inflector.ordinalize(self)
end
+
+ # Ordinal returns the suffix used to denote the position
+ # in an ordered sequence such as 1st, 2nd, 3rd, 4th.
+ #
+ # 1.ordinal # => "st"
+ # 2.ordinal # => "nd"
+ # 1002.ordinal # => "nd"
+ # 1003.ordinal # => "rd"
+ # -11.ordinal # => "th"
+ # -1001.ordinal # => "st"
+ #
+ def ordinal
+ ActiveSupport::Inflector.ordinal(self)
+ end
end
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index ac2a63d3a1..af92b869fd 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -106,9 +106,11 @@ class Module
unless options.is_a?(Hash) && to = options[:to]
raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)."
end
- prefix, to, allow_nil = options[:prefix], options[:to], options[:allow_nil]
- if prefix == true && to.to_s =~ /^[^a-z_]/
+ to = to.to_s
+ prefix, allow_nil = options.values_at(:prefix, :allow_nil)
+
+ if prefix == true && to =~ /^[^a-z_]/
raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
end
@@ -122,10 +124,8 @@ class Module
file, line = caller.first.split(':', 2)
line = line.to_i
- methods.each do |method|
- method = method.to_s
-
- if allow_nil
+ if allow_nil
+ methods.each do |method|
module_eval(<<-EOS, file, line - 2)
def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block)
if #{to} || #{to}.respond_to?(:#{method}) # if client || client.respond_to?(:name)
@@ -133,7 +133,9 @@ class Module
end # end
end # end
EOS
- else
+ end
+ else
+ methods.each do |method|
exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
module_eval(<<-EOS, file, line - 1)
diff --git a/activesupport/lib/active_support/core_ext/object/blank.rb b/activesupport/lib/active_support/core_ext/object/blank.rb
index 7271671908..d67711f3b8 100644
--- a/activesupport/lib/active_support/core_ext/object/blank.rb
+++ b/activesupport/lib/active_support/core_ext/object/blank.rb
@@ -1,5 +1,4 @@
# encoding: utf-8
-require 'active_support/core_ext/string/encoding'
class Object
# An object is blank if it's false, empty, or a whitespace string.
diff --git a/activesupport/lib/active_support/core_ext/object/duplicable.rb b/activesupport/lib/active_support/core_ext/object/duplicable.rb
index 9d044eba71..9d1630bb7c 100644
--- a/activesupport/lib/active_support/core_ext/object/duplicable.rb
+++ b/activesupport/lib/active_support/core_ext/object/duplicable.rb
@@ -104,3 +104,16 @@ class Module
false
end
end
+
+require 'bigdecimal'
+class BigDecimal
+ begin
+ BigDecimal.new('4.56').dup
+
+ def duplicable?
+ true
+ end
+ rescue TypeError
+ # can't dup, so use superclass implementation
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/proc.rb b/activesupport/lib/active_support/core_ext/proc.rb
index 94bb5fb0cb..cd63740940 100644
--- a/activesupport/lib/active_support/core_ext/proc.rb
+++ b/activesupport/lib/active_support/core_ext/proc.rb
@@ -1,7 +1,10 @@
require "active_support/core_ext/kernel/singleton_class"
+require "active_support/deprecation"
class Proc #:nodoc:
def bind(object)
+ ActiveSupport::Deprecation.warn 'Proc#bind is deprecated and will be removed in future versions', caller
+
block, time = self, Time.now
object.class_eval do
method_name = "__bind_#{time.to_i}_#{time.usec}"
diff --git a/activesupport/lib/active_support/core_ext/range/overlaps.rb b/activesupport/lib/active_support/core_ext/range/overlaps.rb
index 7df653b53f..603657c180 100644
--- a/activesupport/lib/active_support/core_ext/range/overlaps.rb
+++ b/activesupport/lib/active_support/core_ext/range/overlaps.rb
@@ -3,6 +3,6 @@ class Range
# (1..5).overlaps?(4..6) # => true
# (1..5).overlaps?(7..9) # => false
def overlaps?(other)
- include?(other.first) || other.include?(first)
+ cover?(other.first) || other.cover?(first)
end
end
diff --git a/activesupport/lib/active_support/core_ext/string.rb b/activesupport/lib/active_support/core_ext/string.rb
index 72522d395c..ab49af55bf 100644
--- a/activesupport/lib/active_support/core_ext/string.rb
+++ b/activesupport/lib/active_support/core_ext/string.rb
@@ -9,6 +9,5 @@ require 'active_support/core_ext/string/behavior'
require 'active_support/core_ext/string/interpolation'
require 'active_support/core_ext/string/output_safety'
require 'active_support/core_ext/string/exclude'
-require 'active_support/core_ext/string/encoding'
require 'active_support/core_ext/string/strip'
require 'active_support/core_ext/string/inquiry'
diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb
index dd780da157..4903687b73 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -103,29 +103,39 @@ module ActiveSupport #:nodoc:
end
end
- def[](*args)
- new_safe_buffer = super
- new_safe_buffer.instance_eval { @dirty = false }
- new_safe_buffer
+ def [](*args)
+ return super if args.size < 2
+
+ if html_safe?
+ new_safe_buffer = super
+ new_safe_buffer.instance_eval { @html_safe = true }
+ new_safe_buffer
+ else
+ to_str[*args]
+ end
end
def safe_concat(value)
- raise SafeConcatError if dirty?
+ raise SafeConcatError unless html_safe?
original_concat(value)
end
def initialize(*)
- @dirty = false
+ @html_safe = true
super
end
def initialize_copy(other)
super
- @dirty = other.dirty?
+ @html_safe = other.html_safe?
+ end
+
+ def clone_empty
+ self[0, 0]
end
def concat(value)
- if dirty? || value.html_safe?
+ if !html_safe? || value.html_safe?
super(value)
else
super(ERB::Util.h(value))
@@ -138,7 +148,7 @@ module ActiveSupport #:nodoc:
end
def html_safe?
- !dirty?
+ defined?(@html_safe) && @html_safe
end
def to_s
@@ -161,18 +171,12 @@ module ActiveSupport #:nodoc:
end # end
def #{unsafe_method}!(*args) # def capitalize!(*args)
- @dirty = true # @dirty = true
+ @html_safe = false # @html_safe = false
super # super
end # end
EOT
end
end
-
- protected
-
- def dirty?
- @dirty
- end
end
end
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index 5e433f5dd9..5076697c04 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -67,7 +67,7 @@ class Time
end
# Returns a new Time where one or more of the elements have been changed according to the +options+ parameter. The time options
- # (hour, minute, sec, usec) reset cascadingly, so if only the hour is passed, then minute, sec, and usec is set to 0. If the hour and
+ # (hour, min, sec, usec) reset cascadingly, so if only the hour is passed, then minute, sec, and usec is set to 0. If the hour and
# minute is passed, then sec and usec is set to 0.
def change(options)
::Time.send(
@@ -145,6 +145,7 @@ class Time
def prev_year
years_ago(1)
end
+ alias_method :last_year, :prev_year
# Short-hand for years_since(1)
def next_year
@@ -155,6 +156,7 @@ class Time
def prev_month
months_ago(1)
end
+ alias_method :last_month, :prev_month
# Short-hand for months_since(1)
def next_month
@@ -199,6 +201,7 @@ class Time
def prev_week(day = :monday)
ago(1.week).beginning_of_week.since(DAYS_INTO_WEEK[day].day).change(:hour => 0)
end
+ alias_method :last_week, :prev_week
# Returns a new Time representing the start of the given day in next week (default is :monday).
def next_week(day = :monday)
@@ -273,9 +276,9 @@ class Time
beginning_of_day..end_of_day
end
- # Returns a Range representing the whole week of the current time.
- def all_week
- beginning_of_week..end_of_week
+ # Returns a Range representing the whole week of the current time. Week starts on start_day (default is :monday, i.e. end of Sunday).
+ def all_week(start_day = :monday)
+ beginning_of_week(start_day)..end_of_week(start_day)
end
# Returns a Range representing the whole month of the current time.
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index 2c5950edf5..745a131524 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -129,16 +129,14 @@ module ActiveSupport #:nodoc:
# Add a set of modules to the watch stack, remembering the initial constants
def watch_namespaces(namespaces)
- watching = []
- namespaces.map do |namespace|
+ @watching << namespaces.map do |namespace|
module_name = Dependencies.to_constant_name(namespace)
original_constants = Dependencies.qualified_const_defined?(module_name) ?
Inflector.constantize(module_name).local_constants : []
- watching << module_name
@stack[module_name] << original_constants
+ module_name
end
- @watching << watching
end
private
@@ -365,7 +363,7 @@ module ActiveSupport #:nodoc:
# Record history *after* loading so first load gets warnings.
history << expanded
- return result
+ result
end
# Is the provided constant path defined?
@@ -434,7 +432,7 @@ module ActiveSupport #:nodoc:
mod = Module.new
into.const_set const_name, mod
autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path)
- return mod
+ mod
end
# Load the file at the provided path. +const_paths+ is a set of qualified
@@ -458,7 +456,7 @@ module ActiveSupport #:nodoc:
autoloaded_constants.concat newly_defined_paths unless load_once_path?(path)
autoloaded_constants.uniq!
log "loading #{path} defined #{newly_defined_paths * ', '}" unless newly_defined_paths.empty?
- return result
+ result
end
# Return the constant path for the provided parent and constant name.
@@ -505,7 +503,7 @@ module ActiveSupport #:nodoc:
raise NameError,
"uninitialized constant #{qualified_name}",
- caller.reject {|l| l.starts_with? __FILE__ }
+ caller.reject { |l| l.starts_with? __FILE__ }
end
# Remove the constants that have been autoloaded, and those that have been
@@ -543,10 +541,7 @@ module ActiveSupport #:nodoc:
def safe_get(key)
key = key.name if key.respond_to?(:name)
- @store[key] || begin
- klass = Inflector.safe_constantize(key)
- @store[key] = klass
- end
+ @store[key] ||= Inflector.safe_constantize(key)
end
def store(klass)
@@ -600,10 +595,10 @@ module ActiveSupport #:nodoc:
def mark_for_unload(const_desc)
name = to_constant_name const_desc
if explicitly_unloadable_constants.include? name
- return false
+ false
else
explicitly_unloadable_constants << name
- return true
+ true
end
end
@@ -631,10 +626,10 @@ module ActiveSupport #:nodoc:
return new_constants unless aborting
log "Error during loading, removing partially loaded constants "
- new_constants.each {|c| remove_constant(c) }.clear
+ new_constants.each { |c| remove_constant(c) }.clear
end
- return []
+ []
end
# Convert the provided const desc to a qualified constant name (as a string).
@@ -663,7 +658,7 @@ module ActiveSupport #:nodoc:
constantized.before_remove_const if constantized.respond_to?(:before_remove_const)
parent.instance_eval { remove_const to_remove }
- return true
+ true
end
protected
diff --git a/activesupport/lib/active_support/dependencies/autoload.rb b/activesupport/lib/active_support/dependencies/autoload.rb
index 4c771da096..a1626ebeba 100644
--- a/activesupport/lib/active_support/dependencies/autoload.rb
+++ b/activesupport/lib/active_support/dependencies/autoload.rb
@@ -9,13 +9,16 @@ module ActiveSupport
@@eager_autoload = false
def autoload(const_name, path = @@at_path)
- full = [self.name, @@under_path, const_name.to_s, path].compact.join("::")
- location = path || Inflector.underscore(full)
+ unless path
+ full = [name, @@under_path, const_name.to_s, path].compact.join("::")
+ path = Inflector.underscore(full)
+ end
if @@eager_autoload
- @@autoloads[const_name] = location
+ @@autoloads[const_name] = path
end
- super const_name, location
+
+ super const_name, path
end
def autoload_under(path)
diff --git a/activesupport/lib/active_support/file_update_checker.rb b/activesupport/lib/active_support/file_update_checker.rb
index 2ede084e95..fe22b9515b 100644
--- a/activesupport/lib/active_support/file_update_checker.rb
+++ b/activesupport/lib/active_support/file_update_checker.rb
@@ -1,5 +1,3 @@
-require "active_support/core_ext/array/extract_options"
-
module ActiveSupport
# \FileUpdateChecker specifies the API used by Rails to watch files
# and control reloading. The API depends on four methods:
@@ -93,10 +91,10 @@ module ActiveSupport
def updated_at #:nodoc:
@updated_at || begin
- all = []
- all.concat @files.select { |f| File.exists?(f) }
+ all = @files.select { |f| File.exists?(f) }
all.concat Dir[@glob] if @glob
- all.map { |path| File.mtime(path) }.max || Time.at(0)
+ all.map! { |path| File.mtime(path) }
+ all.max || Time.at(0)
end
end
@@ -104,13 +102,16 @@ module ActiveSupport
hash.freeze # Freeze so changes aren't accidently pushed
return if hash.empty?
- globs = []
- hash.each do |key, value|
- globs << "#{key}/**/*#{compile_ext(value)}"
+ globs = hash.map do |key, value|
+ "#{escape(key)}/**/*#{compile_ext(value)}"
end
"{#{globs.join(",")}}"
end
+ def escape(key)
+ key.gsub(',','\,')
+ end
+
def compile_ext(array) #:nodoc:
array = Array(array)
return if array.empty?
diff --git a/activesupport/lib/active_support/gzip.rb b/activesupport/lib/active_support/gzip.rb
index f7036315d6..420b965c87 100644
--- a/activesupport/lib/active_support/gzip.rb
+++ b/activesupport/lib/active_support/gzip.rb
@@ -1,6 +1,5 @@
require 'zlib'
require 'stringio'
-require 'active_support/core_ext/string/encoding'
module ActiveSupport
# A convenient wrapper for the zlib standard library that allows compression/decompression of strings with gzip.
diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb
index 674e4acfd6..91459f3e5b 100644
--- a/activesupport/lib/active_support/hash_with_indifferent_access.rb
+++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb
@@ -1,12 +1,11 @@
require 'active_support/core_ext/hash/keys'
-# This class has dubious semantics and we only have it so that
-# people can write <tt>params[:key]</tt> instead of <tt>params['key']</tt>
-# and they get the same value for both keys.
-
module ActiveSupport
+ # This class has dubious semantics and we only have it so that
+ # people can write <tt>params[:key]</tt> instead of <tt>params['key']</tt>
+ # and they get the same value for both keys.
class HashWithIndifferentAccess < Hash
-
+
# Always returns true, so that <tt>Array#extract_options!</tt> finds members of this class.
def extractable_options?
true
@@ -43,6 +42,10 @@ module ActiveSupport
end
end
+ def self.[](*args)
+ new.merge(Hash[*args])
+ end
+
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
alias_method :regular_update, :update unless method_defined?(:regular_update)
diff --git a/activesupport/lib/active_support/inflections.rb b/activesupport/lib/active_support/inflections.rb
index 527cce2594..b3eb1333ca 100644
--- a/activesupport/lib/active_support/inflections.rb
+++ b/activesupport/lib/active_support/inflections.rb
@@ -2,7 +2,7 @@ module ActiveSupport
Inflector.inflections do |inflect|
inflect.plural(/$/, 's')
inflect.plural(/s$/i, 's')
- inflect.plural(/(ax|test)is$/i, '\1es')
+ inflect.plural(/^(ax|test)is$/i, '\1es')
inflect.plural(/(octop|vir)us$/i, '\1i')
inflect.plural(/(octop|vir)i$/i, '\1i')
inflect.plural(/(alias|status)$/i, '\1es')
@@ -23,10 +23,11 @@ module ActiveSupport
inflect.plural(/(quiz)$/i, '\1zes')
inflect.singular(/s$/i, '')
+ inflect.singular(/(ss)$/i, '\1')
inflect.singular(/(n)ews$/i, '\1ews')
inflect.singular(/([ti])a$/i, '\1um')
- inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
- inflect.singular(/(^analy)ses$/i, '\1sis')
+ inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '\1\2sis')
+ inflect.singular(/(^analy)(sis|ses)$/i, '\1sis')
inflect.singular(/([^f])ves$/i, '\1fe')
inflect.singular(/(hive)s$/i, '\1')
inflect.singular(/(tive)s$/i, '\1')
@@ -36,12 +37,13 @@ module ActiveSupport
inflect.singular(/(m)ovies$/i, '\1ovie')
inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
inflect.singular(/(m|l)ice$/i, '\1ouse')
- inflect.singular(/(bus)es$/i, '\1')
+ inflect.singular(/(bus)(es)?$/i, '\1')
inflect.singular(/(o)es$/i, '\1')
inflect.singular(/(shoe)s$/i, '\1')
- inflect.singular(/(cris|ax|test)es$/i, '\1is')
- inflect.singular(/(octop|vir)i$/i, '\1us')
- inflect.singular(/(alias|status)es$/i, '\1')
+ inflect.singular(/(cris|test)(is|es)$/i, '\1is')
+ inflect.singular(/^(a)x[ie]s$/i, '\1xis')
+ inflect.singular(/(octop|vir)(us|i)$/i, '\1us')
+ inflect.singular(/(alias|status)(es)?$/i, '\1')
inflect.singular(/^(ox)en/i, '\1')
inflect.singular(/(vert|ind)ices$/i, '\1ex')
inflect.singular(/(matr)ices$/i, '\1ix')
diff --git a/activesupport/lib/active_support/inflector/inflections.rb b/activesupport/lib/active_support/inflector/inflections.rb
index 90bb62f57b..13b23d627a 100644
--- a/activesupport/lib/active_support/inflector/inflections.rb
+++ b/activesupport/lib/active_support/inflector/inflections.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/array/prepend_and_append'
+
module ActiveSupport
module Inflector
# A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
@@ -26,6 +28,13 @@ module ActiveSupport
@plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/
end
+ # Private, for the test suite.
+ def initialize_dup(orig)
+ %w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope|
+ instance_variable_set("@#{scope}", orig.send(scope).dup)
+ end
+ end
+
# Specifies a new acronym. An acronym must be specified as it will appear in a camelized string. An underscore
# string that contains the acronym will retain the acronym when passed to `camelize`, `humanize`, or `titleize`.
# A camelized string that contains the acronym will maintain the acronym when titleized or humanized, and will
@@ -82,7 +91,7 @@ module ActiveSupport
def plural(rule, replacement)
@uncountables.delete(rule) if rule.is_a?(String)
@uncountables.delete(replacement)
- @plurals.insert(0, [rule, replacement])
+ @plurals.prepend([rule, replacement])
end
# Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
@@ -90,7 +99,7 @@ module ActiveSupport
def singular(rule, replacement)
@uncountables.delete(rule) if rule.is_a?(String)
@uncountables.delete(replacement)
- @singulars.insert(0, [rule, replacement])
+ @singulars.prepend([rule, replacement])
end
# Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
@@ -134,7 +143,7 @@ module ActiveSupport
# human /_cnt$/i, '\1_count'
# human "legacy_col_person_name", "Name"
def human(rule, replacement)
- @humans.insert(0, [rule, replacement])
+ @humans.prepend([rule, replacement])
end
# Clears the loaded inflections within a given scope (default is <tt>:all</tt>).
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index 12dc86aeac..4cebad742f 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
require 'active_support/inflector/inflections'
module ActiveSupport
@@ -92,9 +94,9 @@ module ActiveSupport
# "author_id" # => "Author"
def humanize(lower_case_and_underscored_word)
result = lower_case_and_underscored_word.to_s.dup
- inflections.humans.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
+ inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
result.gsub!(/_id$/, "")
- result.gsub!(/_/, ' ')
+ result.tr!('_', ' ')
result.gsub(/([a-z\d]*)/i) { |match|
"#{inflections.acronyms[match] || match.downcase}"
}.gsub(/^\w/) { $&.upcase }
@@ -112,7 +114,7 @@ module ActiveSupport
# "TheManWithoutAPast".titleize # => "The Man Without A Past"
# "raiders_of_the_lost_ark".titleize # => "Raiders Of The Lost Ark"
def titleize(word)
- humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
+ humanize(underscore(word)).gsub(/\b(['’`]?[a-z])/) { $1.capitalize }
end
# Create the name of a table like Rails does for models to table names. This method
@@ -146,7 +148,7 @@ module ActiveSupport
# Example:
# "puni_puni" # => "puni-puni"
def dasherize(underscored_word)
- underscored_word.gsub(/_/, '-')
+ underscored_word.tr('_', '-')
end
# Removes the module part from the expression in the string:
@@ -210,11 +212,9 @@ module ActiveSupport
names = camel_cased_word.split('::')
names.shift if names.empty? || names.first.empty?
- constant = Object
- names.each do |name|
- constant = constant.const_get(name, false)
+ names.inject(Object) do |constant, name|
+ constant.const_get(name, false)
end
- constant
end
# Tries to find a constant with the name specified in the argument string:
@@ -250,6 +250,29 @@ module ActiveSupport
end
end
+ # Returns the suffix that should be added to a number to denote the position
+ # in an ordered sequence such as 1st, 2nd, 3rd, 4th.
+ #
+ # Examples:
+ # ordinal(1) # => "st"
+ # ordinal(2) # => "nd"
+ # ordinal(1002) # => "nd"
+ # ordinal(1003) # => "rd"
+ # ordinal(-11) # => "th"
+ # ordinal(-1021) # => "st"
+ def ordinal(number)
+ if (11..13).include?(number.to_i.abs % 100)
+ "th"
+ else
+ case number.to_i.abs % 10
+ when 1; "st"
+ when 2; "nd"
+ when 3; "rd"
+ else "th"
+ end
+ end
+ end
+
# Turns a number into an ordinal string used to denote the position in an
# ordered sequence such as 1st, 2nd, 3rd, 4th.
#
@@ -261,16 +284,7 @@ module ActiveSupport
# ordinalize(-11) # => "-11th"
# ordinalize(-1021) # => "-1021st"
def ordinalize(number)
- if (11..13).include?(number.to_i.abs % 100)
- "#{number}th"
- else
- case number.to_i.abs % 10
- when 1; "#{number}st"
- when 2; "#{number}nd"
- when 3; "#{number}rd"
- else "#{number}th"
- end
- end
+ "#{number}#{ordinal(number)}"
end
private
@@ -294,10 +308,10 @@ module ActiveSupport
def apply_inflections(word, rules)
result = word.to_s.dup
- if word.empty? || inflections.uncountables.any? { |inflection| result =~ /\b#{inflection}\Z/i }
+ if word.empty? || inflections.uncountables.include?(result.downcase[/\b\w+\Z/])
result
else
- rules.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
+ rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
result
end
end
diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb
index fcd83f8dea..b2adfea273 100644
--- a/activesupport/lib/active_support/json/encoding.rb
+++ b/activesupport/lib/active_support/json/encoding.rb
@@ -1,7 +1,6 @@
require 'active_support/core_ext/object/to_json'
require 'active_support/core_ext/module/delegation'
require 'active_support/json/variable'
-require 'active_support/ordered_hash'
require 'bigdecimal'
require 'active_support/core_ext/big_decimal/conversions' # for #to_s
@@ -239,8 +238,7 @@ class Hash
# use encoder as a proxy to call as_json on all values in the subset, to protect from circular references
encoder = options && options[:encoder] || ActiveSupport::JSON::Encoding::Encoder.new(options)
- result = self.is_a?(ActiveSupport::OrderedHash) ? ActiveSupport::OrderedHash : Hash
- result[subset.map { |k, v| [k.to_s, encoder.as_json(v, options)] }]
+ Hash[subset.map { |k, v| [k.to_s, encoder.as_json(v, options)] }]
end
def encode_json(encoder)
diff --git a/activesupport/lib/active_support/lazy_load_hooks.rb b/activesupport/lib/active_support/lazy_load_hooks.rb
index 82507c1e03..c167efc1a7 100644
--- a/activesupport/lib/active_support/lazy_load_hooks.rb
+++ b/activesupport/lib/active_support/lazy_load_hooks.rb
@@ -1,32 +1,32 @@
-# lazy_load_hooks allows rails to lazily load a lot of components and thus making the app boot faster. Because of
-# this feature now there is no need to require <tt>ActiveRecord::Base</tt> at boot time purely to apply configuration. Instead
-# a hook is registered that applies configuration once <tt>ActiveRecord::Base</tt> is loaded. Here <tt>ActiveRecord::Base</tt> is used
-# as example but this feature can be applied elsewhere too.
-#
-# Here is an example where +on_load+ method is called to register a hook.
-#
-# initializer "active_record.initialize_timezone" do
-# ActiveSupport.on_load(:active_record) do
-# self.time_zone_aware_attributes = true
-# self.default_timezone = :utc
-# end
-# end
-#
-# When the entirety of +activerecord/lib/active_record/base.rb+ has been evaluated then +run_load_hooks+ is invoked.
-# The very last line of +activerecord/lib/active_record/base.rb+ is:
-#
-# ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
-#
module ActiveSupport
- @load_hooks = Hash.new {|h,k| h[k] = [] }
- @loaded = {}
+ # lazy_load_hooks allows rails to lazily load a lot of components and thus making the app boot faster. Because of
+ # this feature now there is no need to require <tt>ActiveRecord::Base</tt> at boot time purely to apply configuration. Instead
+ # a hook is registered that applies configuration once <tt>ActiveRecord::Base</tt> is loaded. Here <tt>ActiveRecord::Base</tt> is used
+ # as example but this feature can be applied elsewhere too.
+ #
+ # Here is an example where +on_load+ method is called to register a hook.
+ #
+ # initializer "active_record.initialize_timezone" do
+ # ActiveSupport.on_load(:active_record) do
+ # self.time_zone_aware_attributes = true
+ # self.default_timezone = :utc
+ # end
+ # end
+ #
+ # When the entirety of +activerecord/lib/active_record/base.rb+ has been evaluated then +run_load_hooks+ is invoked.
+ # The very last line of +activerecord/lib/active_record/base.rb+ is:
+ #
+ # ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
+ #
+ @load_hooks = Hash.new { |h,k| h[k] = [] }
+ @loaded = Hash.new { |h,k| h[k] = [] }
def self.on_load(name, options = {}, &block)
- if base = @loaded[name]
+ @loaded[name].each do |base|
execute_hook(base, options, block)
- else
- @load_hooks[name] << [block, options]
end
+
+ @load_hooks[name] << [block, options]
end
def self.execute_hook(base, options, block)
@@ -38,7 +38,7 @@ module ActiveSupport
end
def self.run_load_hooks(name, base = Object)
- @loaded[name] = base
+ @loaded[name] << base
@load_hooks[name].each do |hook, options|
execute_hook(base, options, hook)
end
diff --git a/activesupport/lib/active_support/log_subscriber.rb b/activesupport/lib/active_support/log_subscriber.rb
index 58938cdc3d..d2a6e1bd82 100644
--- a/activesupport/lib/active_support/log_subscriber.rb
+++ b/activesupport/lib/active_support/log_subscriber.rb
@@ -3,7 +3,7 @@ require 'active_support/core_ext/class/attribute'
module ActiveSupport
# ActiveSupport::LogSubscriber is an object set to consume ActiveSupport::Notifications
- # with the sole purpose of logging them. The log subscriber dispatches notifications to
+ # with the sole purpose of logging them. The log subscriber dispatches notifications to
# a registered object based on its given namespace.
#
# An example would be Active Record log subscriber responsible for logging queries:
@@ -75,7 +75,8 @@ module ActiveSupport
@@flushable_loggers ||= begin
loggers = log_subscribers.map(&:logger)
loggers.uniq!
- loggers.select { |l| l.respond_to?(:flush) }
+ loggers.select! { |l| l.respond_to?(:flush) }
+ loggers
end
end
@@ -101,8 +102,7 @@ module ActiveSupport
%w(info debug warn error fatal unknown).each do |level|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
def #{level}(progname = nil, &block)
- return unless logger
- logger.#{level}(progname, &block)
+ logger.#{level}(progname, &block) if logger
end
METHOD
end
diff --git a/activesupport/lib/active_support/multibyte/unicode.rb b/activesupport/lib/active_support/multibyte/unicode.rb
index a0a8f3c97e..cb89d45c92 100644
--- a/activesupport/lib/active_support/multibyte/unicode.rb
+++ b/activesupport/lib/active_support/multibyte/unicode.rb
@@ -10,7 +10,7 @@ module ActiveSupport
NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
# The Unicode version that is supported by the implementation
- UNICODE_VERSION = '6.0.0'
+ UNICODE_VERSION = '6.1.0'
# The default normalization used for operations that require normalization. It can be set to any of the
# normalizations in NORMALIZATION_FORMS.
diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb
index 13f675c654..8cf7bdafda 100644
--- a/activesupport/lib/active_support/notifications.rb
+++ b/activesupport/lib/active_support/notifications.rb
@@ -1,3 +1,6 @@
+require 'active_support/notifications/instrumenter'
+require 'active_support/notifications/fanout'
+
module ActiveSupport
# = Notifications
#
@@ -105,10 +108,6 @@ module ActiveSupport
# to log subscribers in a thread. You can use any queue implementation you want.
#
module Notifications
- autoload :Instrumenter, 'active_support/notifications/instrumenter'
- autoload :Event, 'active_support/notifications/instrumenter'
- autoload :Fanout, 'active_support/notifications/fanout'
-
@instrumenters = Hash.new { |h,k| h[k] = notifier.listening?(k) }
class << self
diff --git a/activesupport/lib/active_support/notifications/fanout.rb b/activesupport/lib/active_support/notifications/fanout.rb
index a9aa5464e9..17c99089c1 100644
--- a/activesupport/lib/active_support/notifications/fanout.rb
+++ b/activesupport/lib/active_support/notifications/fanout.rb
@@ -9,18 +9,25 @@ module ActiveSupport
end
def subscribe(pattern = nil, block = Proc.new)
- subscriber = Subscriber.new(pattern, block).tap do |s|
- @subscribers << s
- end
+ subscriber = Subscribers.new pattern, block
+ @subscribers << subscriber
@listeners_for.clear
subscriber
end
def unsubscribe(subscriber)
- @subscribers.reject! {|s| s.matches?(subscriber)}
+ @subscribers.reject! { |s| s.matches?(subscriber) }
@listeners_for.clear
end
+ def start(name, id, payload)
+ listeners_for(name).each { |s| s.start(name, id, payload) }
+ end
+
+ def finish(name, id, payload)
+ listeners_for(name).each { |s| s.finish(name, id, payload) }
+ end
+
def publish(name, *args)
listeners_for(name).each { |s| s.publish(name, *args) }
end
@@ -37,23 +44,89 @@ module ActiveSupport
def wait
end
- class Subscriber #:nodoc:
- def initialize(pattern, delegate)
- @pattern = pattern
- @delegate = delegate
+ module Subscribers # :nodoc:
+ def self.new(pattern, listener)
+ if listener.respond_to?(:call)
+ subscriber = Timed.new pattern, listener
+ else
+ subscriber = Evented.new pattern, listener
+ end
+
+ unless pattern
+ AllMessages.new(subscriber)
+ else
+ subscriber
+ end
end
- def publish(message, *args)
- @delegate.call(message, *args)
+ class Evented #:nodoc:
+ def initialize(pattern, delegate)
+ @pattern = pattern
+ @delegate = delegate
+ end
+
+ def start(name, id, payload)
+ @delegate.start name, id, payload
+ end
+
+ def finish(name, id, payload)
+ @delegate.finish name, id, payload
+ end
+
+ def subscribed_to?(name)
+ @pattern === name.to_s
+ end
+
+ def matches?(subscriber_or_name)
+ self === subscriber_or_name ||
+ @pattern && @pattern === subscriber_or_name
+ end
end
- def subscribed_to?(name)
- !@pattern || @pattern === name.to_s
+ class Timed < Evented
+ def initialize(pattern, delegate)
+ @timestack = Hash.new { |h,id|
+ h[id] = Hash.new { |ids,name| ids[name] = [] }
+ }
+ super
+ end
+
+ def publish(name, *args)
+ @delegate.call name, *args
+ end
+
+ def start(name, id, payload)
+ @timestack[id][name].push Time.now
+ end
+
+ def finish(name, id, payload)
+ started = @timestack[id][name].pop
+ @delegate.call(name, started, Time.now, id, payload)
+ end
end
- def matches?(subscriber_or_name)
- self === subscriber_or_name ||
- @pattern && @pattern === subscriber_or_name
+ class AllMessages # :nodoc:
+ def initialize(delegate)
+ @delegate = delegate
+ end
+
+ def start(name, id, payload)
+ @delegate.start name, id, payload
+ end
+
+ def finish(name, id, payload)
+ @delegate.finish name, id, payload
+ end
+
+ def publish(name, *args)
+ @delegate.publish name, *args
+ end
+
+ def subscribed_to?(name)
+ true
+ end
+
+ alias :matches? :===
end
end
end
diff --git a/activesupport/lib/active_support/notifications/instrumenter.rb b/activesupport/lib/active_support/notifications/instrumenter.rb
index 3941c285a2..58e292c658 100644
--- a/activesupport/lib/active_support/notifications/instrumenter.rb
+++ b/activesupport/lib/active_support/notifications/instrumenter.rb
@@ -1,7 +1,6 @@
-require 'active_support/core_ext/module/delegation'
-
module ActiveSupport
module Notifications
+ # Instrumentors are stored in a thread local.
class Instrumenter
attr_reader :id
@@ -14,15 +13,14 @@ module ActiveSupport
# and publish it. Notice that events get sent even if an error occurs
# in the passed-in block
def instrument(name, payload={})
- started = Time.now
-
+ @notifier.start(name, @id, payload)
begin
yield
rescue Exception => e
payload[:exception] = [e.class.name, e.message]
raise e
ensure
- @notifier.publish(name, started, Time.now, @id, payload)
+ @notifier.finish(name, @id, payload)
end
end
diff --git a/activesupport/lib/active_support/ordered_options.rb b/activesupport/lib/active_support/ordered_options.rb
index 9e5a5d0246..538e41e0eb 100644
--- a/activesupport/lib/active_support/ordered_options.rb
+++ b/activesupport/lib/active_support/ordered_options.rb
@@ -1,5 +1,3 @@
-require 'active_support/ordered_hash'
-
# Usually key value pairs are handled something like this:
#
# h = {}
@@ -17,7 +15,7 @@ require 'active_support/ordered_hash'
# h.girl # => 'Mary'
#
module ActiveSupport #:nodoc:
- class OrderedOptions < OrderedHash
+ class OrderedOptions < Hash
alias_method :_get, :[] # preserve the original #[] method
protected :_get # make it protected
diff --git a/activesupport/lib/active_support/railtie.rb b/activesupport/lib/active_support/railtie.rb
index f696716cc8..d1c62c5087 100644
--- a/activesupport/lib/active_support/railtie.rb
+++ b/activesupport/lib/active_support/railtie.rb
@@ -8,30 +8,6 @@ module ActiveSupport
initializer "active_support.deprecation_behavior" do |app|
if deprecation = app.config.active_support.deprecation
ActiveSupport::Deprecation.behavior = deprecation
- else
- defaults = {"development" => :log,
- "production" => :notify,
- "test" => :stderr}
-
- env = Rails.env
-
- if defaults.key?(env)
- msg = "You did not specify how you would like Rails to report " \
- "deprecation notices for your #{env} environment, please " \
- "set config.active_support.deprecation to :#{defaults[env]} " \
- "at config/environments/#{env}.rb"
-
- warn msg
- ActiveSupport::Deprecation.behavior = defaults[env]
- else
- msg = "You did not specify how you would like Rails to report " \
- "deprecation notices for your #{env} environment, please " \
- "set config.active_support.deprecation to :log, :notify or " \
- ":stderr at config/environments/#{env}.rb"
-
- warn msg
- ActiveSupport::Deprecation.behavior = :stderr
- end
end
end
@@ -42,8 +18,7 @@ module ActiveSupport
zone_default = Time.find_zone!(app.config.time_zone)
unless zone_default
- raise \
- 'Value assigned to config.time_zone not recognized.' +
+ raise 'Value assigned to config.time_zone not recognized. ' \
'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
end
diff --git a/activesupport/lib/active_support/rescuable.rb b/activesupport/lib/active_support/rescuable.rb
index 0f4a06468a..85e84bc203 100644
--- a/activesupport/lib/active_support/rescuable.rb
+++ b/activesupport/lib/active_support/rescuable.rb
@@ -108,7 +108,11 @@ module ActiveSupport
when Symbol
method(rescuer)
when Proc
- rescuer.bind(self)
+ if rescuer.arity == 0
+ Proc.new { instance_exec(&rescuer) }
+ else
+ Proc.new { |_exception| instance_exec(_exception, &rescuer) }
+ end
end
end
end
diff --git a/activesupport/lib/active_support/ruby/shim.rb b/activesupport/lib/active_support/ruby/shim.rb
index 41fd866481..13e96b3596 100644
--- a/activesupport/lib/active_support/ruby/shim.rb
+++ b/activesupport/lib/active_support/ruby/shim.rb
@@ -12,5 +12,4 @@ require 'active_support/core_ext/date_time/conversions'
require 'active_support/core_ext/enumerable'
require 'active_support/core_ext/string/conversions'
require 'active_support/core_ext/string/interpolation'
-require 'active_support/core_ext/string/encoding'
require 'active_support/core_ext/time/conversions'
diff --git a/activesupport/lib/active_support/tagged_logging.rb b/activesupport/lib/active_support/tagged_logging.rb
index f6ad861353..538a36f6d9 100644
--- a/activesupport/lib/active_support/tagged_logging.rb
+++ b/activesupport/lib/active_support/tagged_logging.rb
@@ -13,7 +13,7 @@ module ActiveSupport
# This is used by the default Rails.logger as configured by Railties to make it easy to stamp log lines
# with subdomains, request ids, and anything else to aid debugging of multi-user production applications.
module TaggedLogging
- class Formatter < ActiveSupport::Logger::SimpleFormatter # :nodoc:
+ module Formatter # :nodoc:
# This method is invoked when a log event occurs
def call(severity, timestamp, progname, msg)
super(severity, timestamp, progname, "#{tags_text}#{msg}")
@@ -37,7 +37,7 @@ module ActiveSupport
end
def self.new(logger)
- logger.formatter = Formatter.new
+ logger.formatter.extend Formatter
logger.extend(self)
end
@@ -45,7 +45,7 @@ module ActiveSupport
tags = formatter.current_tags
new_tags = new_tags.flatten.reject(&:blank?)
tags.concat new_tags
- yield
+ yield self
ensure
tags.pop(new_tags.size)
end
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 35f400f9df..ce46c46092 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -1,28 +1,28 @@
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/try'
-# The TimeZone class serves as a wrapper around TZInfo::Timezone instances. It allows us to do the following:
-#
-# * Limit the set of zones provided by TZInfo to a meaningful subset of 142 zones.
-# * Retrieve and display zones with a friendlier name (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
-# * Lazily load TZInfo::Timezone instances only when they're needed.
-# * Create ActiveSupport::TimeWithZone instances via TimeZone's +local+, +parse+, +at+ and +now+ methods.
-#
-# If you set <tt>config.time_zone</tt> in the Rails Application, you can access this TimeZone object via <tt>Time.zone</tt>:
-#
-# # application.rb:
-# class Application < Rails::Application
-# config.time_zone = "Eastern Time (US & Canada)"
-# end
-#
-# Time.zone # => #<TimeZone:0x514834...>
-# Time.zone.name # => "Eastern Time (US & Canada)"
-# Time.zone.now # => Sun, 18 May 2008 14:30:44 EDT -04:00
-#
-# The version of TZInfo bundled with Active Support only includes the definitions necessary to support the zones
-# defined by the TimeZone class. If you need to use zones that aren't defined by TimeZone, you'll need to install the TZInfo gem
-# (if a recent version of the gem is installed locally, this will be used instead of the bundled version.)
module ActiveSupport
+ # The TimeZone class serves as a wrapper around TZInfo::Timezone instances. It allows us to do the following:
+ #
+ # * Limit the set of zones provided by TZInfo to a meaningful subset of 142 zones.
+ # * Retrieve and display zones with a friendlier name (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
+ # * Lazily load TZInfo::Timezone instances only when they're needed.
+ # * Create ActiveSupport::TimeWithZone instances via TimeZone's +local+, +parse+, +at+ and +now+ methods.
+ #
+ # If you set <tt>config.time_zone</tt> in the Rails Application, you can access this TimeZone object via <tt>Time.zone</tt>:
+ #
+ # # application.rb:
+ # class Application < Rails::Application
+ # config.time_zone = "Eastern Time (US & Canada)"
+ # end
+ #
+ # Time.zone # => #<TimeZone:0x514834...>
+ # Time.zone.name # => "Eastern Time (US & Canada)"
+ # Time.zone.now # => Sun, 18 May 2008 14:30:44 EDT -04:00
+ #
+ # The version of TZInfo bundled with Active Support only includes the definitions necessary to support the zones
+ # defined by the TimeZone class. If you need to use zones that aren't defined by TimeZone, you'll need to install the TZInfo gem
+ # (if a recent version of the gem is installed locally, this will be used instead of the bundled version.)
class TimeZone
# Keys are Rails TimeZone names, values are TZInfo identifiers
MAPPING = {
@@ -168,8 +168,7 @@ module ActiveSupport
"Auckland" => "Pacific/Auckland",
"Wellington" => "Pacific/Auckland",
"Nuku'alofa" => "Pacific/Tongatapu"
- }.each { |name, zone| name.freeze; zone.freeze }
- MAPPING.freeze
+ }
UTC_OFFSET_WITH_COLON = '%s%02d:%02d'
UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.sub(':', '')
@@ -267,7 +266,7 @@ module ActiveSupport
# Time.zone.parse('22:30:00') # => Fri, 31 Dec 1999 22:30:00 HST -10:00
def parse(str, now=now)
date_parts = Date._parse(str)
- return if date_parts.blank?
+ return if date_parts.empty?
time = Time.parse(str, now) rescue DateTime.parse(str)
if date_parts[:offset].nil?
ActiveSupport::TimeWithZone.new(nil, self, time)
@@ -282,7 +281,7 @@ module ActiveSupport
# Time.zone = 'Hawaii' # => "Hawaii"
# Time.zone.now # => Wed, 23 Jan 2008 20:24:27 HST -10:00
def now
- Time.now.utc.in_time_zone(self)
+ time_now.utc.in_time_zone(self)
end
# Return the current date in this time zone.
@@ -391,5 +390,11 @@ module ActiveSupport
end
end
end
+
+ private
+
+ def time_now
+ Time.now
+ end
end
end
diff --git a/activesupport/lib/active_support/values/unicode_tables.dat b/activesupport/lib/active_support/values/unicode_tables.dat
index 7edc4663e8..df17a8cccf 100644
--- a/activesupport/lib/active_support/values/unicode_tables.dat
+++ b/activesupport/lib/active_support/values/unicode_tables.dat
Binary files differ
diff --git a/activesupport/lib/active_support/xml_mini/jdom.rb b/activesupport/lib/active_support/xml_mini/jdom.rb
index dbb6c71907..4551dd2f2d 100644
--- a/activesupport/lib/active_support/xml_mini/jdom.rb
+++ b/activesupport/lib/active_support/xml_mini/jdom.rb
@@ -12,7 +12,6 @@ java_import org.xml.sax.InputSource unless defined? InputSource
java_import org.xml.sax.Attributes unless defined? Attributes
java_import org.w3c.dom.Node unless defined? Node
-# = XmlMini JRuby JDOM implementation
module ActiveSupport
module XmlMini_JDOM #:nodoc:
extend self
diff --git a/activesupport/lib/active_support/xml_mini/libxml.rb b/activesupport/lib/active_support/xml_mini/libxml.rb
index 16570c6aea..26556598fd 100644
--- a/activesupport/lib/active_support/xml_mini/libxml.rb
+++ b/activesupport/lib/active_support/xml_mini/libxml.rb
@@ -2,7 +2,6 @@ require 'libxml'
require 'active_support/core_ext/object/blank'
require 'stringio'
-# = XmlMini LibXML implementation
module ActiveSupport
module XmlMini_LibXML #:nodoc:
extend self
diff --git a/activesupport/lib/active_support/xml_mini/libxmlsax.rb b/activesupport/lib/active_support/xml_mini/libxmlsax.rb
index 2536b1f33e..acc018fd2d 100644
--- a/activesupport/lib/active_support/xml_mini/libxmlsax.rb
+++ b/activesupport/lib/active_support/xml_mini/libxmlsax.rb
@@ -2,9 +2,8 @@ require 'libxml'
require 'active_support/core_ext/object/blank'
require 'stringio'
-# = XmlMini LibXML implementation using a SAX-based parser
module ActiveSupport
- module XmlMini_LibXMLSAX
+ module XmlMini_LibXMLSAX #:nodoc:
extend self
# Class that will build the hash while the XML document
diff --git a/activesupport/lib/active_support/xml_mini/nokogiri.rb b/activesupport/lib/active_support/xml_mini/nokogiri.rb
index 04ec9e8ab8..bb0a52bdcf 100644
--- a/activesupport/lib/active_support/xml_mini/nokogiri.rb
+++ b/activesupport/lib/active_support/xml_mini/nokogiri.rb
@@ -7,7 +7,6 @@ end
require 'active_support/core_ext/object/blank'
require 'stringio'
-# = XmlMini Nokogiri implementation
module ActiveSupport
module XmlMini_Nokogiri #:nodoc:
extend self
diff --git a/activesupport/lib/active_support/xml_mini/nokogirisax.rb b/activesupport/lib/active_support/xml_mini/nokogirisax.rb
index 93fd3dfe57..30b94aac47 100644
--- a/activesupport/lib/active_support/xml_mini/nokogirisax.rb
+++ b/activesupport/lib/active_support/xml_mini/nokogirisax.rb
@@ -7,9 +7,8 @@ end
require 'active_support/core_ext/object/blank'
require 'stringio'
-# = XmlMini Nokogiri implementation using a SAX-based parser
module ActiveSupport
- module XmlMini_NokogiriSAX
+ module XmlMini_NokogiriSAX #:nodoc:
extend self
# Class that will build the hash while the XML document
diff --git a/activesupport/lib/active_support/xml_mini/rexml.rb b/activesupport/lib/active_support/xml_mini/rexml.rb
index a13ad10118..a2a87337a6 100644
--- a/activesupport/lib/active_support/xml_mini/rexml.rb
+++ b/activesupport/lib/active_support/xml_mini/rexml.rb
@@ -2,7 +2,6 @@ require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/object/blank'
require 'stringio'
-# = XmlMini ReXML implementation
module ActiveSupport
module XmlMini_REXML #:nodoc:
extend self