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/cache.rb26
-rw-r--r--activesupport/lib/active_support/cache/file_store.rb9
-rw-r--r--activesupport/lib/active_support/cache/mem_cache_store.rb50
-rw-r--r--activesupport/lib/active_support/cache/null_store.rb5
-rw-r--r--activesupport/lib/active_support/cache/strategy/local_cache.rb13
-rw-r--r--activesupport/lib/active_support/callbacks.rb21
-rw-r--r--activesupport/lib/active_support/concurrency/latch.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/big_decimal/conversions.rb15
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/date/calculations.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/date_and_time/calculations.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/conversions.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/hash/indifferent_access.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/hash/keys.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/integer/time.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/marshal.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/module/anonymous.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/module/remove_method.rb20
-rw-r--r--activesupport/lib/active_support/core_ext/numeric/conversions.rb37
-rw-r--r--activesupport/lib/active_support/core_ext/object/deep_dup.rb12
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/time/conversions.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/time/zones.rb2
-rw-r--r--activesupport/lib/active_support/dependencies.rb8
-rw-r--r--activesupport/lib/active_support/deprecation/method_wrappers.rb56
-rw-r--r--activesupport/lib/active_support/deprecation/proxy_wrappers.rb2
-rw-r--r--activesupport/lib/active_support/deprecation/reporting.rb2
-rw-r--r--activesupport/lib/active_support/gem_version.rb2
-rw-r--r--activesupport/lib/active_support/hash_with_indifferent_access.rb19
-rw-r--r--activesupport/lib/active_support/inflector/inflections.rb2
-rw-r--r--activesupport/lib/active_support/inflector/transliterate.rb7
-rw-r--r--activesupport/lib/active_support/key_generator.rb6
-rw-r--r--activesupport/lib/active_support/log_subscriber/test_helper.rb3
-rw-r--r--activesupport/lib/active_support/multibyte/chars.rb8
-rw-r--r--activesupport/lib/active_support/multibyte/unicode.rb2
-rw-r--r--activesupport/lib/active_support/notifications/fanout.rb2
-rw-r--r--activesupport/lib/active_support/number_helper.rb4
-rw-r--r--activesupport/lib/active_support/number_helper/number_to_human_converter.rb6
-rw-r--r--activesupport/lib/active_support/ordered_options.rb2
-rw-r--r--activesupport/lib/active_support/per_thread_registry.rb6
-rw-r--r--activesupport/lib/active_support/railtie.rb2
-rw-r--r--activesupport/lib/active_support/testing/assertions.rb2
-rw-r--r--activesupport/lib/active_support/testing/deprecation.rb17
-rw-r--r--activesupport/lib/active_support/testing/file_fixtures.rb2
-rw-r--r--activesupport/lib/active_support/testing/isolation.rb18
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb57
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb18
50 files changed, 325 insertions, 208 deletions
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index 8253a76383..d0e53eaf05 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -277,13 +277,18 @@ module ActiveSupport
options = merged_options(options)
key = namespaced_key(name, options)
- cached_entry = find_cached_entry(key, name, options) unless options[:force]
- entry = handle_expired_entry(cached_entry, key, options)
+ instrument(:read, name, options) do |payload|
+ cached_entry = read_entry(key, options) unless options[:force]
+ payload[:super_operation] = :fetch if payload
+ entry = handle_expired_entry(cached_entry, key, options)
- if entry
- get_entry_value(entry, name, options)
- else
- save_block_result_to_cache(name, options) { |_name| yield _name }
+ if entry
+ payload[:hit] = true if payload
+ get_entry_value(entry, name, options)
+ else
+ payload[:hit] = false if payload
+ save_block_result_to_cache(name, options) { |_name| yield _name }
+ end
end
else
read(name, options)
@@ -533,7 +538,7 @@ module ActiveSupport
end
def instrument(operation, key, options = nil)
- log { "Cache #{operation}: #{key}#{options.blank? ? "" : " (#{options.inspect})"}" }
+ log { "Cache #{operation}: #{namespaced_key(key, options)}#{options.blank? ? "" : " (#{options.inspect})"}" }
payload = { :key => key }
payload.merge!(options) if options.is_a?(Hash)
@@ -556,13 +561,6 @@ module ActiveSupport
logger.debug(yield)
end
- def find_cached_entry(key, name, options)
- instrument(:read, name, options) do |payload|
- payload[:super_operation] = :fetch if payload
- read_entry(key, options)
- end
- end
-
def handle_expired_entry(entry, key, options)
if entry && entry.expired?
race_ttl = options[:race_condition_ttl].to_i
diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb
index e6a8b84214..9a88fc286a 100644
--- a/activesupport/lib/active_support/cache/file_store.rb
+++ b/activesupport/lib/active_support/cache/file_store.rb
@@ -10,6 +10,7 @@ module ActiveSupport
# FileStore implements the Strategy::LocalCache strategy which implements
# an in-memory cache inside of a block.
class FileStore < Store
+ prepend Strategy::LocalCache
attr_reader :cache_path
DIR_FORMATTER = "%03X"
@@ -20,7 +21,6 @@ module ActiveSupport
def initialize(cache_path, options = nil)
super(options)
@cache_path = cache_path.to_s
- extend Strategy::LocalCache
end
# Deletes all items from the cache. In this case it deletes all the entries in the specified
@@ -119,11 +119,12 @@ module ActiveSupport
# Translate a key into a file path.
def key_file_path(key)
- if key.size > FILEPATH_MAX_SIZE
- key = Digest::MD5.hexdigest(key)
+ fname = URI.encode_www_form_component(key)
+
+ if fname.size > FILEPATH_MAX_SIZE
+ fname = Digest::MD5.hexdigest(key)
end
- fname = URI.encode_www_form_component(key)
hash = Zlib.adler32(fname)
hash, dir_1 = hash.divmod(0x1000)
dir_2 = hash.modulo(0x1000)
diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb
index 47133bf550..e2f536ef1e 100644
--- a/activesupport/lib/active_support/cache/mem_cache_store.rb
+++ b/activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -24,6 +24,31 @@ module ActiveSupport
# MemCacheStore implements the Strategy::LocalCache strategy which implements
# an in-memory cache inside of a block.
class MemCacheStore < Store
+ # Provide support for raw values in the local cache strategy.
+ module LocalCacheWithRaw # :nodoc:
+ protected
+ def read_entry(key, options)
+ entry = super
+ if options[:raw] && local_cache && entry
+ entry = deserialize_entry(entry.value)
+ end
+ entry
+ end
+
+ def write_entry(key, entry, options) # :nodoc:
+ retval = super
+ if options[:raw] && local_cache && retval
+ raw_entry = Entry.new(entry.value.to_s)
+ raw_entry.expires_at = entry.expires_at
+ local_cache.write_entry(key, raw_entry, options)
+ end
+ retval
+ end
+ end
+
+ prepend Strategy::LocalCache
+ prepend LocalCacheWithRaw
+
ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
# Creates a new Dalli::Client instance with specified addresses and options.
@@ -63,9 +88,6 @@ module ActiveSupport
UNIVERSAL_OPTIONS.each{|name| mem_cache_options.delete(name)}
@data = self.class.build_mem_cache(*(addresses + [mem_cache_options]))
end
-
- extend Strategy::LocalCache
- extend LocalCacheWithRaw
end
# Reads multiple values from the cache using a single call to the
@@ -181,28 +203,6 @@ module ActiveSupport
nil
end
end
-
- # Provide support for raw values in the local cache strategy.
- module LocalCacheWithRaw # :nodoc:
- protected
- def read_entry(key, options)
- entry = super
- if options[:raw] && local_cache && entry
- entry = deserialize_entry(entry.value)
- end
- entry
- end
-
- def write_entry(key, entry, options) # :nodoc:
- retval = super
- if options[:raw] && local_cache && retval
- raw_entry = Entry.new(entry.value.to_s)
- raw_entry.expires_at = entry.expires_at
- local_cache.write_entry(key, raw_entry, options)
- end
- retval
- end
- end
end
end
end
diff --git a/activesupport/lib/active_support/cache/null_store.rb b/activesupport/lib/active_support/cache/null_store.rb
index 4427eaafcd..0564ce5312 100644
--- a/activesupport/lib/active_support/cache/null_store.rb
+++ b/activesupport/lib/active_support/cache/null_store.rb
@@ -8,10 +8,7 @@ module ActiveSupport
# be cached inside blocks that utilize this strategy. See
# ActiveSupport::Cache::Strategy::LocalCache for more details.
class NullStore < Store
- def initialize(options = nil)
- super(options)
- extend Strategy::LocalCache
- end
+ prepend Strategy::LocalCache
def clear(options = nil)
end
diff --git a/activesupport/lib/active_support/cache/strategy/local_cache.rb b/activesupport/lib/active_support/cache/strategy/local_cache.rb
index fe5bc82c30..4e2d3e9875 100644
--- a/activesupport/lib/active_support/cache/strategy/local_cache.rb
+++ b/activesupport/lib/active_support/cache/strategy/local_cache.rb
@@ -48,6 +48,10 @@ module ActiveSupport
@data.clear
end
+ def fetch(*args, &block)
+ @data.fetch(*args, &block)
+ end
+
def read_entry(key, options)
@data[key]
end
@@ -98,13 +102,12 @@ module ActiveSupport
protected
def read_entry(key, options) # :nodoc:
- if local_cache
- entry = local_cache.read_entry(key, options)
- unless entry
+ if cache = local_cache
+ cache.fetch(key) do
entry = super
- local_cache.write_entry(key, entry, options)
+ cache.write_entry(key, entry, options)
+ entry
end
- entry
else
super
end
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 3db9ea2ac0..d43fde03a9 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -4,6 +4,7 @@ require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/kernel/singleton_class'
+require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/string/filters'
require 'active_support/deprecation'
require 'thread'
@@ -66,6 +67,12 @@ module ActiveSupport
CALLBACK_FILTER_TYPES = [:before, :after, :around]
+ # If true, Active Record and Active Model callbacks returning +false+ will
+ # halt the entire callback chain and display a deprecation message.
+ # If false, callback chains will only be halted by calling +throw :abort+.
+ # Defaults to +true+.
+ mattr_accessor(:halt_and_display_warning_on_return_false) { true }
+
# Runs the callbacks for the given event.
#
# Calls the before and around callbacks in the order they were set, yields
@@ -450,12 +457,6 @@ module ActiveSupport
attr_reader :name, :config
- # If true, any callback returning +false+ will halt the entire callback
- # chain and display a deprecation message. If false, callback chains will
- # only be halted by calling +throw :abort+. Defaults to +true+.
- class_attribute :halt_and_display_warning_on_return_false
- self.halt_and_display_warning_on_return_false = true
-
def initialize(name, config)
@name = name
@config = {
@@ -747,20 +748,20 @@ module ActiveSupport
protected
- def get_callbacks(name)
+ def get_callbacks(name) # :nodoc:
send "_#{name}_callbacks"
end
- def set_callbacks(name, callbacks)
+ def set_callbacks(name, callbacks) # :nodoc:
send "_#{name}_callbacks=", callbacks
end
- def deprecated_false_terminator
+ def deprecated_false_terminator # :nodoc:
Proc.new do |target, result_lambda|
terminate = true
catch(:abort) do
result = result_lambda.call if result_lambda.is_a?(Proc)
- if CallbackChain.halt_and_display_warning_on_return_false && result == false
+ if Callbacks.halt_and_display_warning_on_return_false && result == false
display_deprecation_warning_for_false_terminator
else
terminate = false
diff --git a/activesupport/lib/active_support/concurrency/latch.rb b/activesupport/lib/active_support/concurrency/latch.rb
index 7b8df0df04..4abe5ece6f 100644
--- a/activesupport/lib/active_support/concurrency/latch.rb
+++ b/activesupport/lib/active_support/concurrency/latch.rb
@@ -1,4 +1,4 @@
-require 'concurrent/atomics'
+require 'concurrent/atomic/count_down_latch'
module ActiveSupport
module Concurrency
@@ -8,7 +8,7 @@ module ActiveSupport
ActiveSupport::Deprecation.warn("ActiveSupport::Concurrency::Latch is deprecated. Please use Concurrent::CountDownLatch instead.")
super(count)
end
-
+
alias_method :release, :count_down
def await
diff --git a/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb b/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb
index 234283e792..22fc7ecf92 100644
--- a/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb
@@ -1,15 +1,14 @@
require 'bigdecimal'
require 'bigdecimal/util'
-class BigDecimal
- DEFAULT_STRING_FORMAT = 'F'
- alias_method :to_default_s, :to_s
+module ActiveSupport
+ module BigDecimalWithDefaultFormat #:nodoc:
+ DEFAULT_STRING_FORMAT = 'F'
- def to_s(format = nil, options = nil)
- if format.is_a?(Symbol)
- to_formatted_s(format, options || {})
- else
- to_default_s(format || DEFAULT_STRING_FORMAT)
+ def to_s(format = nil)
+ super(format || DEFAULT_STRING_FORMAT)
end
end
end
+
+BigDecimal.prepend(ActiveSupport::BigDecimalWithDefaultFormat)
diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb
index f2b7bb3ef1..802d988af2 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -75,11 +75,15 @@ class Class
instance_predicate = options.fetch(:instance_predicate, true)
attrs.each do |name|
+ remove_possible_singleton_method(name)
define_singleton_method(name) { nil }
+
+ remove_possible_singleton_method("#{name}?")
define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
ivar = "@#{name}"
+ remove_possible_singleton_method("#{name}=")
define_singleton_method("#{name}=") do |val|
singleton_class.class_eval do
remove_possible_method(name)
@@ -110,10 +114,15 @@ class Class
self.class.public_send name
end
end
+
+ remove_possible_method "#{name}?"
define_method("#{name}?") { !!public_send(name) } if instance_predicate
end
- attr_writer name if instance_writer
+ if instance_writer
+ remove_possible_method "#{name}="
+ attr_writer name
+ end
end
end
end
diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb
index c60e833441..d589b67bf7 100644
--- a/activesupport/lib/active_support/core_ext/date/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date/calculations.rb
@@ -26,7 +26,7 @@ class Date
Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
end
- # Returns week start day symbol (e.g. :monday), or raises an ArgumentError for invalid day symbol.
+ # Returns week start day symbol (e.g. :monday), or raises an +ArgumentError+ for invalid day symbol.
def find_beginning_of_week!(week_start)
raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start)
week_start
diff --git a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb
index 40811dafc0..e079af594d 100644
--- a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb
@@ -135,7 +135,7 @@ module DateAndTime
end
alias :at_end_of_quarter :end_of_quarter
- # Return a new date/time at the beginning of the year.
+ # Returns a new date/time at the beginning of the year.
#
# today = Date.today # => Fri, 10 Jul 2015
# today.beginning_of_year # => Thu, 01 Jan 2015
diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
index 2a9c09fc29..f59d05b214 100644
--- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
@@ -40,6 +40,8 @@ class DateTime
alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
alias_method :to_s, :to_formatted_s
+ # Returns a formatted string of the offset from UTC, or an alternative
+ # string if the time zone is already UTC.
#
# datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
# datetime.formatted_offset # => "-06:00"
diff --git a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
index 28cb3e2a3b..6df7b4121b 100644
--- a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
+++ b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
@@ -6,7 +6,7 @@ class Hash
#
# { a: 1 }.with_indifferent_access['a'] # => 1
def with_indifferent_access
- ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self)
+ ActiveSupport::HashWithIndifferentAccess.new(self)
end
# Called when object is nested under an object that receives
diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb
index 963c6a8e67..8b2366c4b3 100644
--- a/activesupport/lib/active_support/core_ext/hash/keys.rb
+++ b/activesupport/lib/active_support/core_ext/hash/keys.rb
@@ -64,7 +64,7 @@ class Hash
alias_method :to_options!, :symbolize_keys!
# Validates all keys in a hash match <tt>*valid_keys</tt>, raising
- # ArgumentError on a mismatch.
+ # +ArgumentError+ on a mismatch.
#
# Note that keys are treated differently than HashWithIndifferentAccess,
# meaning that string and symbol keys will not match.
diff --git a/activesupport/lib/active_support/core_ext/integer/time.rb b/activesupport/lib/active_support/core_ext/integer/time.rb
index f0b7382ef3..87185b024f 100644
--- a/activesupport/lib/active_support/core_ext/integer/time.rb
+++ b/activesupport/lib/active_support/core_ext/integer/time.rb
@@ -23,7 +23,7 @@ class Integer
alias :month :months
def years
- ActiveSupport::Duration.new(self * 365.25.days, [[:years, self]])
+ ActiveSupport::Duration.new(self * 365.25.days.to_i, [[:years, self]])
end
alias :year :years
end
diff --git a/activesupport/lib/active_support/core_ext/marshal.rb b/activesupport/lib/active_support/core_ext/marshal.rb
index 20a0856e71..e333b26133 100644
--- a/activesupport/lib/active_support/core_ext/marshal.rb
+++ b/activesupport/lib/active_support/core_ext/marshal.rb
@@ -6,7 +6,7 @@ module ActiveSupport
if exc.message.match(%r|undefined class/module (.+)|)
# try loading the class/module
$1.constantize
- # if it is a IO we need to go back to read the object
+ # if it is an IO we need to go back to read the object
source.rewind if source.respond_to?(:rewind)
retry
else
diff --git a/activesupport/lib/active_support/core_ext/module/anonymous.rb b/activesupport/lib/active_support/core_ext/module/anonymous.rb
index 0ecc67a855..510c9a5430 100644
--- a/activesupport/lib/active_support/core_ext/module/anonymous.rb
+++ b/activesupport/lib/active_support/core_ext/module/anonymous.rb
@@ -7,7 +7,7 @@ class Module
# m = Module.new
# m.name # => nil
#
- # +anonymous?+ method returns true if module does not have a name:
+ # +anonymous?+ method returns true if module does not have a name, false otherwise:
#
# Module.new.anonymous? # => true
#
@@ -18,8 +18,10 @@ class Module
# via the +module+ or +class+ keyword or by an explicit assignment:
#
# m = Module.new # creates an anonymous module
- # M = m # => m gets a name here as a side-effect
+ # m.anonymous? # => true
+ # M = m # m gets a name here as a side-effect
# m.name # => "M"
+ # m.anonymous? # => false
def anonymous?
name.nil?
end
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
index a084177b9f..bf175a8a70 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
@@ -53,7 +53,7 @@ class Module
def mattr_reader(*syms)
options = syms.extract_options!
syms.each do |sym|
- raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
+ raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /\A[_A-Za-z]\w*\z/
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
@@#{sym} = nil unless defined? @@#{sym}
@@ -119,7 +119,7 @@ class Module
def mattr_writer(*syms)
options = syms.extract_options!
syms.each do |sym|
- raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
+ raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /\A[_A-Za-z]\w*\z/
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
@@#{sym} = nil unless defined? @@#{sym}
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index 9dc0dee1bd..0d46248582 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -5,10 +5,11 @@ class Module
# option is not used.
class DelegationError < NoMethodError; end
- RUBY_RESERVED_WORDS = Set.new(
- %w(alias and BEGIN begin break case class def defined? do else elsif END
- end ensure false for if in module next nil not or redo rescue retry
- return self super then true undef unless until when while yield)
+ DELEGATION_RESERVED_METHOD_NAMES = Set.new(
+ %w(_ arg args alias and BEGIN begin block break case class def defined? do
+ else elsif END end ensure false for if in module next nil not or redo
+ rescue retry return self super then true undef unless until when while
+ yield)
).freeze
# Provides a +delegate+ class method to easily expose contained objects'
@@ -171,7 +172,7 @@ class Module
line = line.to_i
to = to.to_s
- to = "self.#{to}" if RUBY_RESERVED_WORDS.include?(to)
+ to = "self.#{to}" if DELEGATION_RESERVED_METHOD_NAMES.include?(to)
methods.each do |method|
# Attribute writer methods only accept one argument. Makes sure []=
diff --git a/activesupport/lib/active_support/core_ext/module/remove_method.rb b/activesupport/lib/active_support/core_ext/module/remove_method.rb
index 52632d2c6b..d5ec16d68a 100644
--- a/activesupport/lib/active_support/core_ext/module/remove_method.rb
+++ b/activesupport/lib/active_support/core_ext/module/remove_method.rb
@@ -6,10 +6,30 @@ class Module
end
end
+ # Removes the named singleton method, if it exists.
+ def remove_possible_singleton_method(method)
+ singleton_class.instance_eval do
+ remove_possible_method(method)
+ end
+ end
+
# Replaces the existing method definition, if there is one, with the passed
# block as its body.
def redefine_method(method, &block)
+ visibility = method_visibility(method)
remove_possible_method(method)
define_method(method, &block)
+ send(visibility, method)
+ end
+
+ def method_visibility(method) # :nodoc:
+ case
+ when private_method_defined?(method)
+ :private
+ when protected_method_defined?(method)
+ :protected
+ else
+ :public
+ end
end
end
diff --git a/activesupport/lib/active_support/core_ext/numeric/conversions.rb b/activesupport/lib/active_support/core_ext/numeric/conversions.rb
index d5bb11deed..9a3651f29a 100644
--- a/activesupport/lib/active_support/core_ext/numeric/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/numeric/conversions.rb
@@ -1,7 +1,7 @@
require 'active_support/core_ext/big_decimal/conversions'
require 'active_support/number_helper'
-class Numeric
+module ActiveSupport::NumericWithFormat
# Provides options for converting numbers into formatted strings.
# Options are provided for phone numbers, currency, percentage,
@@ -97,7 +97,10 @@ class Numeric
# 1234567.to_s(:human, precision: 1,
# separator: ',',
# significant: false) # => "1,2 Million"
- def to_formatted_s(format = :default, options = {})
+ def to_s(*args)
+ format, options = args
+ options ||= {}
+
case format
when :phone
return ActiveSupport::NumberHelper.number_to_phone(self, options)
@@ -114,32 +117,16 @@ class Numeric
when :human_size
return ActiveSupport::NumberHelper.number_to_human_size(self, options)
else
- self.to_default_s
- end
- end
-
- [Fixnum, Bignum].each do |klass|
- klass.class_eval do
- alias_method :to_default_s, :to_s
- def to_s(base_or_format = 10, options = nil)
- if base_or_format.is_a?(Symbol)
- to_formatted_s(base_or_format, options || {})
- else
- to_default_s(base_or_format)
- end
- end
+ super
end
end
- Float.class_eval do
- alias_method :to_default_s, :to_s
- def to_s(*args)
- if args.empty?
- to_default_s
- else
- to_formatted_s(*args)
- end
- end
+ def to_formatted_s(*args)
+ to_s(*args)
end
+ deprecate to_formatted_s: :to_s
+end
+[Fixnum, Bignum, Float, BigDecimal].each do |klass|
+ klass.prepend(ActiveSupport::NumericWithFormat)
end
diff --git a/activesupport/lib/active_support/core_ext/object/deep_dup.rb b/activesupport/lib/active_support/core_ext/object/deep_dup.rb
index ad5b2af161..8dfeed0066 100644
--- a/activesupport/lib/active_support/core_ext/object/deep_dup.rb
+++ b/activesupport/lib/active_support/core_ext/object/deep_dup.rb
@@ -39,9 +39,15 @@ class Hash
# hash[:a][:c] # => nil
# dup[:a][:c] # => "c"
def deep_dup
- each_with_object(dup) do |(key, value), hash|
- hash.delete(key)
- hash[key.deep_dup] = value.deep_dup
+ hash = dup
+ each_pair do |key, value|
+ if key.frozen? && ::String === key
+ hash[key] = value.deep_dup
+ else
+ hash.delete(key)
+ hash[key.deep_dup] = value.deep_dup
+ end
end
+ hash
end
end
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 8b27ec4413..510fa48189 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -37,7 +37,7 @@ class ERB
if s.html_safe?
s
else
- s.gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE)
+ ActiveSupport::Multibyte::Unicode.tidy_bytes(s).gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE)
end
end
module_function :unwrapped_html_escape
@@ -50,7 +50,7 @@ class ERB
# html_escape_once('&lt;&lt; Accept & Checkout')
# # => "&lt;&lt; Accept &amp; Checkout"
def html_escape_once(s)
- result = s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
+ result = ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
s.html_safe? ? result.html_safe : result
end
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index f13d09f3ad..82e003fc3b 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -16,9 +16,9 @@ class Time
super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
end
- # Return the number of days in the given month.
+ # Returns the number of days in the given month.
# If no year is specified, it will use the current year.
- def days_in_month(month, year = now.year)
+ def days_in_month(month, year = current.year)
if month == 2 && ::Date.gregorian_leap?(year)
29
else
@@ -51,9 +51,9 @@ class Time
# Returns the number of seconds since 00:00:00.
#
- # Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0
- # Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296
- # Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399
+ # Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
+ # Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
+ # Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
def seconds_since_midnight
to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
end
diff --git a/activesupport/lib/active_support/core_ext/time/conversions.rb b/activesupport/lib/active_support/core_ext/time/conversions.rb
index dbf1f2f373..536c4bf525 100644
--- a/activesupport/lib/active_support/core_ext/time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/time/conversions.rb
@@ -6,6 +6,7 @@ class Time
:db => '%Y-%m-%d %H:%M:%S',
:number => '%Y%m%d%H%M%S',
:nsec => '%Y%m%d%H%M%S%9N',
+ :usec => '%Y%m%d%H%M%S%6N',
:time => '%H:%M',
:short => '%d %b %H:%M',
:long => '%B %d, %Y %H:%M',
@@ -24,7 +25,7 @@ class Time
#
# This method is aliased to <tt>to_s</tt>.
#
- # time = Time.now # => Thu Jan 18 06:10:17 CST 2007
+ # time = Time.now # => 2007-01-18 06:10:17 -06:00
#
# time.to_formatted_s(:time) # => "06:10"
# time.to_s(:time) # => "06:10"
@@ -55,7 +56,8 @@ class Time
alias_method :to_default_s, :to_s
alias_method :to_s, :to_formatted_s
- # Returns the UTC offset as an +HH:MM formatted string.
+ # Returns a formatted string of the offset from UTC, or an alternative
+ # string if the time zone is already UTC.
#
# Time.local(2000).formatted_offset # => "-06:00"
# Time.local(2000).formatted_offset(false) # => "-0600"
diff --git a/activesupport/lib/active_support/core_ext/time/zones.rb b/activesupport/lib/active_support/core_ext/time/zones.rb
index 133d3938eb..877dc84ec8 100644
--- a/activesupport/lib/active_support/core_ext/time/zones.rb
+++ b/activesupport/lib/active_support/core_ext/time/zones.rb
@@ -53,7 +53,7 @@ class Time
# Returns a TimeZone instance matching the time zone provided.
# Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
- # Raises an ArgumentError for invalid time zones.
+ # Raises an +ArgumentError+ for invalid time zones.
#
# Time.find_zone! "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
# Time.find_zone! "EST" # => #<ActiveSupport::TimeZone @name="EST" ...>
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index 16b726bcba..af18ff746f 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -1,6 +1,6 @@
require 'set'
require 'thread'
-require 'concurrent'
+require 'concurrent/map'
require 'pathname'
require 'active_support/core_ext/module/aliasing'
require 'active_support/core_ext/module/attribute_accessors'
@@ -25,21 +25,21 @@ module ActiveSupport #:nodoc:
# :doc:
# Execute the supplied block without interference from any
- # concurrent loads
+ # concurrent loads.
def self.run_interlock
Dependencies.interlock.running { yield }
end
# Execute the supplied block while holding an exclusive lock,
# preventing any other thread from being inside a #run_interlock
- # block at the same time
+ # block at the same time.
def self.load_interlock
Dependencies.interlock.loading { yield }
end
# Execute the supplied block while holding an exclusive lock,
# preventing any other thread from being inside a #run_interlock
- # block at the same time
+ # block at the same time.
def self.unload_interlock
Dependencies.interlock.unloading { yield }
end
diff --git a/activesupport/lib/active_support/deprecation/method_wrappers.rb b/activesupport/lib/active_support/deprecation/method_wrappers.rb
index c74e9c40ac..32fe8025fe 100644
--- a/activesupport/lib/active_support/deprecation/method_wrappers.rb
+++ b/activesupport/lib/active_support/deprecation/method_wrappers.rb
@@ -9,37 +9,61 @@ module ActiveSupport
# module Fred
# extend self
#
- # def foo; end
- # def bar; end
- # def baz; end
+ # def aaa; end
+ # def bbb; end
+ # def ccc; end
+ # def ddd; end
+ # def eee; end
# end
#
- # ActiveSupport::Deprecation.deprecate_methods(Fred, :foo, bar: :qux, baz: 'use Bar#baz instead')
- # # => [:foo, :bar, :baz]
+ # Using the default deprecator:
+ # ActiveSupport::Deprecation.deprecate_methods(Fred, :aaa, bbb: :zzz, ccc: 'use Bar#ccc instead')
+ # # => [:aaa, :bbb, :ccc]
#
- # Fred.foo
- # # => "DEPRECATION WARNING: foo is deprecated and will be removed from Rails 4.1."
+ # Fred.aaa
+ # # DEPRECATION WARNING: aaa is deprecated and will be removed from Rails 5.0. (called from irb_binding at (irb):10)
+ # # => nil
#
- # Fred.bar
- # # => "DEPRECATION WARNING: bar is deprecated and will be removed from Rails 4.1 (use qux instead)."
+ # Fred.bbb
+ # # DEPRECATION WARNING: bbb is deprecated and will be removed from Rails 5.0 (use zzz instead). (called from irb_binding at (irb):11)
+ # # => nil
#
- # Fred.baz
- # # => "DEPRECATION WARNING: baz is deprecated and will be removed from Rails 4.1 (use Bar#baz instead)."
+ # Fred.ccc
+ # # DEPRECATION WARNING: ccc is deprecated and will be removed from Rails 5.0 (use Bar#ccc instead). (called from irb_binding at (irb):12)
+ # # => nil
+ #
+ # Passing in a custom deprecator:
+ # custom_deprecator = ActiveSupport::Deprecation.new('next-release', 'MyGem')
+ # ActiveSupport::Deprecation.deprecate_methods(Fred, ddd: :zzz, deprecator: custom_deprecator)
+ # # => [:ddd]
+ #
+ # Fred.ddd
+ # DEPRECATION WARNING: ddd is deprecated and will be removed from MyGem next-release (use zzz instead). (called from irb_binding at (irb):15)
+ # # => nil
+ #
+ # Using a custom deprecator directly:
+ # custom_deprecator = ActiveSupport::Deprecation.new('next-release', 'MyGem')
+ # custom_deprecator.deprecate_methods(Fred, eee: :zzz)
+ # # => [:eee]
+ #
+ # Fred.eee
+ # DEPRECATION WARNING: eee is deprecated and will be removed from MyGem next-release (use zzz instead). (called from irb_binding at (irb):18)
+ # # => nil
def deprecate_methods(target_module, *method_names)
options = method_names.extract_options!
- deprecator = options.delete(:deprecator) || ActiveSupport::Deprecation.instance
+ deprecator = options.delete(:deprecator) || self
method_names += options.keys
- method_names.each do |method_name|
- mod = Module.new do
+ mod = Module.new do
+ method_names.each do |method_name|
define_method(method_name) do |*args, &block|
deprecator.deprecation_warning(method_name, options[method_name])
super(*args, &block)
end
end
-
- target_module.prepend(mod)
end
+
+ target_module.prepend(mod)
end
end
end
diff --git a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
index 6572ff78a6..6f0ad445fc 100644
--- a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
+++ b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
@@ -111,7 +111,7 @@ module ActiveSupport
#
# PLANETS = %w(mercury venus earth mars jupiter saturn uranus neptune pluto)
#
- # (In a later update, the orignal implementation of `PLANETS` has been removed.)
+ # (In a later update, the original implementation of `PLANETS` has been removed.)
#
# PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
# PLANETS = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('PLANETS', 'PLANETS_POST_2006')
diff --git a/activesupport/lib/active_support/deprecation/reporting.rb b/activesupport/lib/active_support/deprecation/reporting.rb
index bbe25c9260..f89fc0fe14 100644
--- a/activesupport/lib/active_support/deprecation/reporting.rb
+++ b/activesupport/lib/active_support/deprecation/reporting.rb
@@ -83,7 +83,7 @@ module ActiveSupport
rails_gem_root = File.expand_path("../../../../..", __FILE__) + "/"
offending_line = callstack.find { |frame|
- !frame.absolute_path.start_with?(rails_gem_root)
+ frame.absolute_path && !frame.absolute_path.start_with?(rails_gem_root)
} || callstack.first
[offending_line.path, offending_line.lineno, offending_line.label]
end
diff --git a/activesupport/lib/active_support/gem_version.rb b/activesupport/lib/active_support/gem_version.rb
index 7068f09d87..ece68bbcb6 100644
--- a/activesupport/lib/active_support/gem_version.rb
+++ b/activesupport/lib/active_support/gem_version.rb
@@ -1,5 +1,5 @@
module ActiveSupport
- # Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>
+ # Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>.
def self.gem_version
Gem::Version.new VERSION::STRING
end
diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb
index 0371f760b0..4ff35a45a1 100644
--- a/activesupport/lib/active_support/hash_with_indifferent_access.rb
+++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb
@@ -59,6 +59,10 @@ module ActiveSupport
if constructor.respond_to?(:to_hash)
super()
update(constructor)
+
+ hash = constructor.to_hash
+ self.default = hash.default if hash.default
+ self.default_proc = hash.default_proc if hash.default_proc
else
super(constructor)
end
@@ -73,11 +77,12 @@ module ActiveSupport
end
def self.new_from_hash_copying_default(hash)
- hash = hash.to_hash
- new(hash).tap do |new_hash|
- new_hash.default = hash.default
- new_hash.default_proc = hash.default_proc if hash.default_proc
- end
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
+ `ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default`
+ has been deprecated, and will be removed in Rails 5.1. The behavior of
+ this method is now identical to the behavior of `.new`.
+ MSG
+ new(hash)
end
def self.[](*args)
@@ -206,7 +211,7 @@ module ActiveSupport
# hash['a'] = nil
# hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
def reverse_merge(other_hash)
- super(self.class.new_from_hash_copying_default(other_hash))
+ super(self.class.new(other_hash))
end
# Same semantics as +reverse_merge+ but modifies the receiver in-place.
@@ -219,7 +224,7 @@ module ActiveSupport
# h = { "a" => 100, "b" => 200 }
# h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
def replace(other_hash)
- super(self.class.new_from_hash_copying_default(other_hash))
+ super(self.class.new(other_hash))
end
# Removes the specified key from the hash.
diff --git a/activesupport/lib/active_support/inflector/inflections.rb b/activesupport/lib/active_support/inflector/inflections.rb
index c3907e9c22..f3e52b48ac 100644
--- a/activesupport/lib/active_support/inflector/inflections.rb
+++ b/activesupport/lib/active_support/inflector/inflections.rb
@@ -1,4 +1,4 @@
-require 'concurrent'
+require 'concurrent/map'
require 'active_support/core_ext/array/prepend_and_append'
require 'active_support/i18n'
diff --git a/activesupport/lib/active_support/inflector/transliterate.rb b/activesupport/lib/active_support/inflector/transliterate.rb
index 7472d4386a..103207fb63 100644
--- a/activesupport/lib/active_support/inflector/transliterate.rb
+++ b/activesupport/lib/active_support/inflector/transliterate.rb
@@ -69,10 +69,12 @@ module ActiveSupport
# parameterize("Donald E. Knuth") # => "donald-e-knuth"
# parameterize("^trés|Jolie-- ") # => "tres-jolie"
def parameterize(string, sep = '-')
- # replace accented chars with their ascii equivalents
+ # Replace accented chars with their ASCII equivalents.
parameterized_string = transliterate(string)
- # Turn unwanted chars into the separator
+
+ # Turn unwanted chars into the separator.
parameterized_string.gsub!(/[^a-z0-9\-_]+/i, sep)
+
unless sep.nil? || sep.empty?
if sep == "-".freeze
re_duplicate_separator = /-{2,}/
@@ -87,6 +89,7 @@ module ActiveSupport
# Remove leading/trailing separator.
parameterized_string.gsub!(re_leading_trailing_separator, ''.freeze)
end
+
parameterized_string.downcase!
parameterized_string
end
diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb
index 6bc3db6ec6..7f73f9ddfc 100644
--- a/activesupport/lib/active_support/key_generator.rb
+++ b/activesupport/lib/active_support/key_generator.rb
@@ -1,8 +1,8 @@
-require 'concurrent'
+require 'concurrent/map'
require 'openssl'
module ActiveSupport
- # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2
+ # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2.
# It can be used to derive a number of keys for various purposes from a given secret.
# This lets Rails applications have a single secure secret, but avoid reusing that
# key in multiple incompatible contexts.
@@ -24,7 +24,7 @@ module ActiveSupport
# CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
# re-executing the key generation process when it's called using the same salt and
- # key_size
+ # key_size.
class CachingKeyGenerator
def initialize(key_generator)
@key_generator = key_generator
diff --git a/activesupport/lib/active_support/log_subscriber/test_helper.rb b/activesupport/lib/active_support/log_subscriber/test_helper.rb
index cbc20c103d..588ed67c81 100644
--- a/activesupport/lib/active_support/log_subscriber/test_helper.rb
+++ b/activesupport/lib/active_support/log_subscriber/test_helper.rb
@@ -10,8 +10,7 @@ module ActiveSupport
# class SyncLogSubscriberTest < ActiveSupport::TestCase
# include ActiveSupport::LogSubscriber::TestHelper
#
- # def setup
- # super
+ # setup do
# ActiveRecord::LogSubscriber.attach_to(:active_record)
# end
#
diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb
index f6a2e7e949..707cf200b5 100644
--- a/activesupport/lib/active_support/multibyte/chars.rb
+++ b/activesupport/lib/active_support/multibyte/chars.rb
@@ -86,7 +86,8 @@ module ActiveSupport #:nodoc:
end
# Works like <tt>String#slice!</tt>, but returns an instance of
- # Chars, or nil if the string was not modified.
+ # Chars, or nil if the string was not modified. The string will not be
+ # modified if the range given is out of bounds
#
# string = 'Welcome'
# string.mb_chars.slice!(3) # => #<ActiveSupport::Multibyte::Chars:0x000000038109b8 @wrapped_string="c">
@@ -94,7 +95,10 @@ module ActiveSupport #:nodoc:
# string.mb_chars.slice!(0..3) # => #<ActiveSupport::Multibyte::Chars:0x00000002eb80a0 @wrapped_string="Welo">
# string # => 'me'
def slice!(*args)
- chars(@wrapped_string.slice!(*args))
+ string_sliced = @wrapped_string.slice!(*args)
+ if string_sliced
+ chars(string_sliced)
+ end
end
# Reverses all characters in the string.
diff --git a/activesupport/lib/active_support/multibyte/unicode.rb b/activesupport/lib/active_support/multibyte/unicode.rb
index 5221a6dfb8..586002b03b 100644
--- a/activesupport/lib/active_support/multibyte/unicode.rb
+++ b/activesupport/lib/active_support/multibyte/unicode.rb
@@ -256,7 +256,7 @@ module ActiveSupport
# * <tt>string</tt> - The string to perform normalization on.
# * <tt>form</tt> - The form you want to normalize in. Should be one of
# the following: <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>.
- # Default is ActiveSupport::Multibyte.default_normalization_form.
+ # Default is ActiveSupport::Multibyte::Unicode.default_normalization_form.
def normalize(string, form=nil)
form ||= @default_normalization_form
# See http://www.unicode.org/reports/tr15, Table 1
diff --git a/activesupport/lib/active_support/notifications/fanout.rb b/activesupport/lib/active_support/notifications/fanout.rb
index 71354dd15f..7798c7ec60 100644
--- a/activesupport/lib/active_support/notifications/fanout.rb
+++ b/activesupport/lib/active_support/notifications/fanout.rb
@@ -1,5 +1,5 @@
require 'mutex_m'
-require 'concurrent'
+require 'concurrent/map'
module ActiveSupport
module Notifications
diff --git a/activesupport/lib/active_support/number_helper.rb b/activesupport/lib/active_support/number_helper.rb
index 504f96961a..248521e677 100644
--- a/activesupport/lib/active_support/number_helper.rb
+++ b/activesupport/lib/active_support/number_helper.rb
@@ -115,8 +115,8 @@ module ActiveSupport
# number_to_percentage(100, precision: 0) # => 100%
# number_to_percentage(1000, delimiter: '.', separator: ',') # => 1.000,000%
# number_to_percentage(302.24398923423, precision: 5) # => 302.24399%
- # number_to_percentage(1000, locale: :fr) # => 1 000,000%
- # number_to_percentage:(1000, precision: nil) # => 1000%
+ # number_to_percentage(1000, locale: :fr) # => 1000,000%
+ # number_to_percentage(1000, precision: nil) # => 1000%
# number_to_percentage('98a') # => 98a%
# number_to_percentage(100, format: '%n %') # => 100.000 %
def number_to_percentage(number, options = {})
diff --git a/activesupport/lib/active_support/number_helper/number_to_human_converter.rb b/activesupport/lib/active_support/number_helper/number_to_human_converter.rb
index 5c6fe2df83..7a1f8171c0 100644
--- a/activesupport/lib/active_support/number_helper/number_to_human_converter.rb
+++ b/activesupport/lib/active_support/number_helper/number_to_human_converter.rb
@@ -20,9 +20,11 @@ module ActiveSupport
exponent = calculate_exponent(units)
@number = number / (10 ** exponent)
+ until (rounded_number = NumberToRoundedConverter.convert(number, options)) != NumberToRoundedConverter.convert(1000, options)
+ @number = number / 1000.0
+ exponent += 3
+ end
unit = determine_unit(units, exponent)
-
- rounded_number = NumberToRoundedConverter.convert(number, options)
format.gsub('%n'.freeze, rounded_number).gsub('%u'.freeze, unit).strip
end
diff --git a/activesupport/lib/active_support/ordered_options.rb b/activesupport/lib/active_support/ordered_options.rb
index 45864990ce..53a55bd986 100644
--- a/activesupport/lib/active_support/ordered_options.rb
+++ b/activesupport/lib/active_support/ordered_options.rb
@@ -20,7 +20,7 @@ module ActiveSupport
# To raise an exception when the value is blank, append a
# bang to the key name, like:
#
- # h.dog! # => raises KeyError
+ # h.dog! # => raises KeyError: key not found: :dog
#
class OrderedOptions < Hash
alias_method :_get, :[] # preserve the original #[] method
diff --git a/activesupport/lib/active_support/per_thread_registry.rb b/activesupport/lib/active_support/per_thread_registry.rb
index ca2e4d5625..506dd950cb 100644
--- a/activesupport/lib/active_support/per_thread_registry.rb
+++ b/activesupport/lib/active_support/per_thread_registry.rb
@@ -43,9 +43,9 @@ module ActiveSupport
protected
def method_missing(name, *args, &block) # :nodoc:
# Caches the method definition as a singleton method of the receiver.
- define_singleton_method(name) do |*a, &b|
- instance.public_send(name, *a, &b)
- end
+ #
+ # By letting #delegate handle it, we avoid an enclosure that'll capture args.
+ singleton_class.delegate name, to: :instance
send(name, *args, &block)
end
diff --git a/activesupport/lib/active_support/railtie.rb b/activesupport/lib/active_support/railtie.rb
index cd0fb51009..845788b669 100644
--- a/activesupport/lib/active_support/railtie.rb
+++ b/activesupport/lib/active_support/railtie.rb
@@ -26,7 +26,7 @@ module ActiveSupport
unless zone_default
raise 'Value assigned to config.time_zone not recognized. ' \
- 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
+ 'Run "rake time:zones:all" for a time zone names list.'
end
Time.zone_default = zone_default
diff --git a/activesupport/lib/active_support/testing/assertions.rb b/activesupport/lib/active_support/testing/assertions.rb
index ae8c15d8bf..29305e0082 100644
--- a/activesupport/lib/active_support/testing/assertions.rb
+++ b/activesupport/lib/active_support/testing/assertions.rb
@@ -3,7 +3,7 @@ require 'active_support/core_ext/object/blank'
module ActiveSupport
module Testing
module Assertions
- # Assert that an expression is not truthy. Passes if <tt>object</tt> is
+ # Asserts that an expression is not truthy. Passes if <tt>object</tt> is
# +nil+ or +false+. "Truthy" means "considered true in a conditional"
# like <tt>if foo</tt>.
#
diff --git a/activesupport/lib/active_support/testing/deprecation.rb b/activesupport/lib/active_support/testing/deprecation.rb
index 6c94c611b6..5dfa14eeba 100644
--- a/activesupport/lib/active_support/testing/deprecation.rb
+++ b/activesupport/lib/active_support/testing/deprecation.rb
@@ -3,8 +3,8 @@ require 'active_support/deprecation'
module ActiveSupport
module Testing
module Deprecation #:nodoc:
- def assert_deprecated(match = nil, &block)
- result, warnings = collect_deprecations(&block)
+ def assert_deprecated(match = nil, deprecator = nil, &block)
+ result, warnings = collect_deprecations(deprecator, &block)
assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
if match
match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
@@ -13,22 +13,23 @@ module ActiveSupport
result
end
- def assert_not_deprecated(&block)
- result, deprecations = collect_deprecations(&block)
+ def assert_not_deprecated(deprecator = nil, &block)
+ result, deprecations = collect_deprecations(deprecator, &block)
assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
result
end
- def collect_deprecations
- old_behavior = ActiveSupport::Deprecation.behavior
+ def collect_deprecations(deprecator = nil)
+ deprecator ||= ActiveSupport::Deprecation
+ old_behavior = deprecator.behavior
deprecations = []
- ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack|
+ deprecator.behavior = Proc.new do |message, callstack|
deprecations << message
end
result = yield
[result, deprecations]
ensure
- ActiveSupport::Deprecation.behavior = old_behavior
+ deprecator.behavior = old_behavior
end
end
end
diff --git a/activesupport/lib/active_support/testing/file_fixtures.rb b/activesupport/lib/active_support/testing/file_fixtures.rb
index 4c6a0801b8..affb84cda5 100644
--- a/activesupport/lib/active_support/testing/file_fixtures.rb
+++ b/activesupport/lib/active_support/testing/file_fixtures.rb
@@ -18,7 +18,7 @@ module ActiveSupport
# Returns a +Pathname+ to the fixture file named +fixture_name+.
#
- # Raises ArgumentError if +fixture_name+ can't be found.
+ # Raises +ArgumentError+ if +fixture_name+ can't be found.
def file_fixture(fixture_name)
path = Pathname.new(File.join(file_fixture_path, fixture_name))
diff --git a/activesupport/lib/active_support/testing/isolation.rb b/activesupport/lib/active_support/testing/isolation.rb
index 1de0a19998..edf8b30a0a 100644
--- a/activesupport/lib/active_support/testing/isolation.rb
+++ b/activesupport/lib/active_support/testing/isolation.rb
@@ -41,7 +41,23 @@ module ActiveSupport
pid = fork do
read.close
yield
- write.puts [Marshal.dump(self.dup)].pack("m")
+ begin
+ if error?
+ failures.map! { |e|
+ begin
+ Marshal.dump e
+ e
+ rescue TypeError
+ ex = Exception.new e.message
+ ex.set_backtrace e.backtrace
+ Minitest::UnexpectedError.new ex
+ end
+ }
+ end
+ result = Marshal.dump(self.dup)
+ end
+
+ write.puts [result].pack("m")
exit!
end
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index a82a7dfea0..79cc748cf5 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -41,6 +41,9 @@ module ActiveSupport
'Time'
end
+ PRECISIONS = Hash.new { |h, n| h[n] = "%FT%T.%#{n}N".freeze }
+ PRECISIONS[0] = '%FT%T'.freeze
+
include Comparable
attr_reader :time_zone
@@ -99,7 +102,7 @@ module ActiveSupport
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
# Time.zone.now.utc? # => false
def utc?
- time_zone.name == 'UTC'
+ period.offset.abbreviation == :UTC || period.offset.abbreviation == :UCT
end
alias_method :gmt?, :utc?
@@ -142,11 +145,7 @@ module ActiveSupport
#
# Time.zone.now.xmlschema # => "2014-12-04T11:02:37-05:00"
def xmlschema(fraction_digits = 0)
- fraction = if fraction_digits.to_i > 0
- (".%06i" % time.usec)[0, fraction_digits.to_i + 1]
- end
-
- "#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(true, 'Z')}"
+ "#{time.strftime(PRECISIONS[fraction_digits.to_i])}#{formatted_offset(true, 'Z'.freeze)}"
end
alias_method :iso8601, :xmlschema
@@ -285,8 +284,8 @@ module ActiveSupport
# the current object's time and the +other+ time.
#
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
- # now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28 EST -05:00
- # now - 1000 # => Sun, 02 Nov 2014 01:09:48 EST -05:00
+ # now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28 EST -05:00
+ # now - 1000 # => Mon, 03 Nov 2014 00:09:48 EST -05:00
#
# If subtracting a Duration of variable length (i.e., years, months, days),
# move backward from #time, otherwise move backward from #utc, for accuracy
@@ -295,8 +294,8 @@ module ActiveSupport
# For instance, a time - 24.hours will go subtract exactly 24 hours, while a
# time - 1.day will subtract 23-25 hours, depending on the day.
#
- # now - 24.hours # => Sat, 01 Nov 2014 02:26:28 EDT -04:00
- # now - 1.day # => Sat, 01 Nov 2014 01:26:28 EDT -04:00
+ # now - 24.hours # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
+ # now - 1.day # => Sun, 02 Nov 2014 00:26:28 EDT -04:00
def -(other)
if other.acts_like?(:time)
to_time - other.to_time
@@ -308,10 +307,48 @@ module ActiveSupport
end
end
+ # Subtracts an interval of time from the current object's time and returns
+ # the result as a new TimeWithZone object.
+ #
+ # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
+ # now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28 EST -05:00
+ # now.ago(1000) # => Mon, 03 Nov 2014 00:09:48 EST -05:00
+ #
+ # If we're subtracting a Duration of variable length (i.e., years, months,
+ # days), move backward from #time, otherwise move backward from #utc, for
+ # accuracy when moving across DST boundaries.
+ #
+ # For instance, <tt>time.ago(24.hours)</tt> will move back exactly 24 hours,
+ # while <tt>time.ago(1.day)</tt> will move back 23-25 hours, depending on
+ # the day.
+ #
+ # now.ago(24.hours) # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
+ # now.ago(1.day) # => Sun, 02 Nov 2014 00:26:28 EDT -04:00
def ago(other)
since(-other)
end
+ # Uses Date to provide precise Time calculations for years, months, and days
+ # according to the proleptic Gregorian calendar. The result is returned as a
+ # new TimeWithZone object.
+ #
+ # The +options+ parameter takes a hash with any of these keys:
+ # <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>,
+ # <tt>:hours</tt>, <tt>:minutes</tt>, <tt>:seconds</tt>.
+ #
+ # If advancing by a value of variable length (i.e., years, weeks, months,
+ # days), move forward from #time, otherwise move forward from #utc, for
+ # accuracy when moving across DST boundaries.
+ #
+ # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
+ # now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
+ # now.advance(seconds: 1) # => Sun, 02 Nov 2014 01:26:29 EDT -04:00
+ # now.advance(minutes: 1) # => Sun, 02 Nov 2014 01:27:28 EDT -04:00
+ # now.advance(hours: 1) # => Sun, 02 Nov 2014 01:26:28 EST -05:00
+ # now.advance(days: 1) # => Mon, 03 Nov 2014 01:26:28 EST -05:00
+ # now.advance(weeks: 1) # => Sun, 09 Nov 2014 01:26:28 EST -05:00
+ # now.advance(months: 1) # => Tue, 02 Dec 2014 01:26:28 EST -05:00
+ # now.advance(years: 1) # => Mon, 02 Nov 2015 01:26:28 EST -05:00
def advance(options)
# If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time,
# otherwise advance from #utc, for accuracy when moving across DST boundaries
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 4502e01b12..6404f65612 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -1,5 +1,5 @@
require 'tzinfo'
-require 'concurrent'
+require 'concurrent/map'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/try'
@@ -26,12 +26,6 @@ module ActiveSupport
# Time.zone # => #<ActiveSupport::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 = {
@@ -285,8 +279,12 @@ module ActiveSupport
end
end
- # Returns the offset of this time zone as a formatted string, of the
- # format "+HH:MM".
+ # Returns a formatted string of the offset from UTC, or an alternative
+ # string if the time zone is already UTC.
+ #
+ # zone = ActiveSupport::TimeZone['Central Time (US & Canada)']
+ # zone.formatted_offset # => "-06:00"
+ # zone.formatted_offset(false) # => "-0600"
def formatted_offset(colon=true, alternate_utc_string = nil)
utc_offset == 0 && alternate_utc_string || self.class.seconds_to_utc_offset(utc_offset, colon)
end
@@ -384,7 +382,7 @@ module ActiveSupport
time_now.utc.in_time_zone(self)
end
- # Return the current date in this time zone.
+ # Returns the current date in this time zone.
def today
tzinfo.now.to_date
end