aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorrick <rick@spacemonkey.local>2008-05-05 23:19:21 -0700
committerrick <rick@spacemonkey.local>2008-05-05 23:19:21 -0700
commit0052938ac5b8894b27fdb9f27b1ed39f0a9ea176 (patch)
treef714643a4043d9fb73b39ec2a114d18f5deeffdd /activesupport
parenteacb5cf0cab6447db78085c8bda6c94dd329ce6b (diff)
parent3cffe92ff066c2b35eef409547db93652c5cccfc (diff)
downloadrails-0052938ac5b8894b27fdb9f27b1ed39f0a9ea176.tar.gz
rails-0052938ac5b8894b27fdb9f27b1ed39f0a9ea176.tar.bz2
rails-0052938ac5b8894b27fdb9f27b1ed39f0a9ea176.zip
Merge commit 'core/master'
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG2
-rw-r--r--activesupport/lib/active_support/cache.rb19
-rw-r--r--activesupport/lib/active_support/cache/file_store.rb4
-rw-r--r--activesupport/lib/active_support/cache/mem_cache_store.rb33
-rw-r--r--activesupport/lib/active_support/cache/memory_store.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/array/conversions.rb51
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute_accessors.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/date/calculations.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/calculations.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/enumerable.rb21
-rw-r--r--activesupport/lib/active_support/core_ext/hash/reverse_merge.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/kernel/daemonizing.rb12
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors.rb12
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/process.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/process/daemon.rb25
-rw-r--r--activesupport/lib/active_support/core_ext/range/include_range.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/range/overlaps.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb10
-rw-r--r--activesupport/lib/active_support/dependencies.rb31
-rw-r--r--activesupport/lib/active_support/inflector.rb27
-rw-r--r--activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb4
-rw-r--r--activesupport/lib/active_support/ordered_options.rb6
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb13
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb439
-rw-r--r--activesupport/lib/active_support/vendor/memcache-client-1.5.0/memcache.rb8
-rw-r--r--activesupport/lib/active_support/whiny_nil.rb6
-rw-r--r--activesupport/test/inflector_test.rb10
-rw-r--r--activesupport/test/ordered_options_test.rb13
29 files changed, 482 insertions, 306 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index a911361d3b..3ee9ed925c 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Added Ruby 1.8 implementation of Process.daemon
+
* Duration #since and #ago with no argument (e.g., 5.days.ago) return TimeWithZone when config.time_zone is set. Introducing Time.current, which returns Time.zone.now if config.time_zone is set, otherwise just returns Time.now [Geoff Buesing]
* Time#since behaves correctly when passed a Duration. Closes #11527 [kemiller]
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index 64394afec4..b3c9c23d9f 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -49,7 +49,7 @@ module ActiveSupport
self
end
- # Pass :force => true to force a cache miss.
+ # Pass <tt>:force => true</tt> to force a cache miss.
def fetch(key, options = {})
@logger_off = true
if !options[:force] && value = read(key, options)
@@ -87,8 +87,25 @@ module ActiveSupport
def delete_matched(matcher, options = nil)
log("delete matched", matcher.inspect, options)
+ end
+
+ def increment(key, amount = 1)
+ log("incrementing", key, amount)
+ if num = read(key)
+ write(key, num + amount)
+ else
+ nil
+ end
end
+ def decrement(key, amount = 1)
+ log("decrementing", key, amount)
+ if num = read(key)
+ write(key, num - amount)
+ else
+ nil
+ end
+ end
private
def log(operation, key, options)
diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb
index 88f9ac19db..16a2509ce2 100644
--- a/activesupport/lib/active_support/cache/file_store.rb
+++ b/activesupport/lib/active_support/cache/file_store.rb
@@ -20,14 +20,14 @@ module ActiveSupport
RAILS_DEFAULT_LOGGER.error "Couldn't create cache directory: #{name} (#{e.message})" if RAILS_DEFAULT_LOGGER
end
- def delete(name, options)
+ def delete(name, options = nil)
super
File.delete(real_file_path(name))
rescue SystemCallError => e
# If there's no cache, then there's nothing to complain about
end
- def delete_matched(matcher, options)
+ def delete_matched(matcher, options = nil)
super
search_dir(@cache_path) do |f|
if f =~ matcher
diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb
index 9b787702b2..bfe7e2ccf3 100644
--- a/activesupport/lib/active_support/cache/mem_cache_store.rb
+++ b/activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -29,12 +29,11 @@ module ActiveSupport
nil
end
- # Set key = value if key isn't already set. Pass :force => true
- # to unconditionally set key = value. Returns a boolean indicating
- # whether the key was set.
+ # Set key = value. Pass :unless_exist => true if you don't
+ # want to update the cache if the key is already set.
def write(key, value, options = nil)
super
- method = options && options[:force] ? :set : :add
+ method = options && options[:unless_exist] ? :add : :set
response = @data.send(method, key, value, expires_in(options), raw?(options))
response == Response::STORED
rescue MemCache::MemCacheError => e
@@ -49,15 +48,37 @@ module ActiveSupport
rescue MemCache::MemCacheError => e
logger.error("MemCacheError (#{e}): #{e.message}")
false
+ end
+
+ def increment(key, amount = 1)
+ log("incrementing", key, amount)
+
+ response = @data.incr(key, amount)
+ response == Response::NOT_FOUND ? nil : response
+ rescue MemCache::MemCacheError
+ nil
end
+ def decrement(key, amount = 1)
+ log("decrement", key, amount)
+
+ response = data.decr(key, amount)
+ response == Response::NOT_FOUND ? nil : response
+ rescue MemCache::MemCacheError
+ nil
+ end
+
def delete_matched(matcher, options = nil)
super
raise "Not supported by Memcache"
- end
-
+ end
+
def clear
@data.flush_all
+ end
+
+ def stats
+ @data.stats
end
private
diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb
index e0aba6b19a..4872e025cd 100644
--- a/activesupport/lib/active_support/cache/memory_store.rb
+++ b/activesupport/lib/active_support/cache/memory_store.rb
@@ -24,6 +24,10 @@ module ActiveSupport
super
@data.delete_if { |k,v| k =~ matcher }
end
+
+ def clear
+ @data.clear
+ end
end
end
end \ No newline at end of file
diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb
index 34b1551abc..a9882828ca 100644
--- a/activesupport/lib/active_support/core_ext/array/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/array/conversions.rb
@@ -67,17 +67,35 @@ module ActiveSupport #:nodoc:
end
end
- # Returns a string that represents this array in XML by sending
- # <tt>to_xml</tt> to each element.
+ # Returns a string that represents this array in XML by sending +to_xml+
+ # to each element. Active Record collections delegate their representation
+ # in XML to this method.
#
- # All elements are expected to respond to <tt>to_xml</tt>, if any of
- # them does not an exception is raised.
+ # All elements are expected to respond to +to_xml+, if any of them does
+ # not an exception is raised.
#
# The root node reflects the class name of the first element in plural
- # if all elements belong to the same type and that's not <tt>Hash</tt>.
- # Otherwise the root element is "records".
+ # if all elements belong to the same type and that's not Hash:
#
- # Root children have as node name the one of the root singularized.
+ # customer.projects.to_xml
+ #
+ # <?xml version="1.0" encoding="UTF-8"?>
+ # <projects type="array">
+ # <project>
+ # <amount type="decimal">20000.0</amount>
+ # <customer-id type="integer">1567</customer-id>
+ # <deal-date type="date">2008-04-09</deal-date>
+ # ...
+ # </project>
+ # <project>
+ # <amount type="decimal">57230.0</amount>
+ # <customer-id type="integer">1567</customer-id>
+ # <deal-date type="date">2008-04-15</deal-date>
+ # ...
+ # </project>
+ # </projects>
+ #
+ # Otherwise the root element is "records":
#
# [{:foo => 1, :bar => 2}, {:baz => 3}].to_xml
#
@@ -92,9 +110,26 @@ module ActiveSupport #:nodoc:
# </record>
# </records>
#
+ # If the collection is empty the root element is "nil-classes" by default:
+ #
+ # [].to_xml
+ #
+ # <?xml version="1.0" encoding="UTF-8"?>
+ # <nil-classes type="array"/>
+ #
+ # To ensure a meaningful root element use the <tt>:root</tt> option:
+ #
+ # customer_with_no_projects.projects.to_xml(:root => "projects")
+ #
+ # <?xml version="1.0" encoding="UTF-8"?>
+ # <projects type="array"/>
+ #
+ # By default root children have as node name the one of the root
+ # singularized. You can change it with the <tt>:children</tt> option.
+ #
# The +options+ hash is passed downwards:
#
- # [Message.find(:first)].to_xml(:skip_types => true)
+ # Message.all.to_xml(:skip_types => true)
#
# <?xml version="1.0" encoding="UTF-8"?>
# <messages>
diff --git a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
index eee61d48c4..186ca69c05 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
@@ -1,6 +1,12 @@
# Extends the class object with class and instance accessors for class attributes,
# just like the native attr* accessors for instance attributes.
-class Class # :nodoc:
+#
+# class Person
+# cattr_accessor :hair_colors
+# end
+#
+# Person.hair_colors = [:brown, :black, :blonde, :red]
+class Class
def cattr_reader(*syms)
syms.flatten.each do |sym|
next if sym.is_a?(Hash)
diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb
index bb561f675f..183471706b 100644
--- a/activesupport/lib/active_support/core_ext/date/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date/calculations.rb
@@ -70,7 +70,7 @@ module ActiveSupport #:nodoc:
end
# Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
- # any of these keys: :years, :months, :weeks, :days.
+ # any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
def advance(options)
d = self
d = d >> options.delete(:years) * 12 if options[:years]
diff --git a/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_time/calculations.rb
index fa444f71b1..155c961a91 100644
--- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb
@@ -42,8 +42,10 @@ module ActiveSupport #:nodoc:
)
end
- # Uses Date to provide precise Time calculations for years, months, and days. The +options+ parameter takes a hash with
- # any of these keys: :years, :months, :weeks, :days, :hours, :minutes, :seconds.
+ # Uses Date to provide precise Time calculations for years, months, and days.
+ # 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>.
def advance(options)
d = to_date.advance(options)
datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb
index 8f111e29fc..f1469aa0e3 100644
--- a/activesupport/lib/active_support/core_ext/enumerable.rb
+++ b/activesupport/lib/active_support/core_ext/enumerable.rb
@@ -8,7 +8,7 @@ module Enumerable
# Example:
#
# latest_transcripts.group_by(&:day).each do |day, transcripts|
- # p "#{day} -> #{transcripts.map(&:class) * ', '}"
+ # p "#{day} -> #{transcripts.map(&:class).join(', ')}"
# end
# "2006-03-01 -> Transcript"
# "2006-02-28 -> Transcript"
@@ -26,21 +26,22 @@ module Enumerable
# Calculates a sum from the elements. Examples:
#
- # payments.sum { |p| p.price * p.tax_rate }
- # payments.sum(&:price)
+ # payments.sum { |p| p.price * p.tax_rate }
+ # payments.sum(&:price)
#
- # This is instead of
+ # The latter is a shortcut for:
#
- # payments.inject { |sum, p| sum + p.price }
+ # payments.inject { |sum, p| sum + p.price }
#
- # Also calculates sums without the use of a block:
+ # It can also calculate the sum without the use of a block.
#
- # [5, 15, 10].sum # => 30
+ # [5, 15, 10].sum # => 30
+ # ["foo", "bar"].sum # => "foobar"
+ # [[1, 2], [3, 1, 5]].sum => [1, 2, 3, 1, 5]
#
- # The default identity (sum of an empty list) is zero.
- # However, you can override this default:
+ # The default sum of an empty list is zero. You can override this default:
#
- # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
+ # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
#
def sum(identity = 0, &block)
return identity unless size > 0
diff --git a/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb b/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb
index 0ec0538024..7af10846e7 100644
--- a/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb
+++ b/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb
@@ -8,7 +8,7 @@ module ActiveSupport #:nodoc:
# options.reverse_merge! :size => 25, :velocity => 10
# end
#
- # The default :size and :velocity is only set if the +options+ passed in doesn't already have those keys set.
+ # The default <tt>:size</tt> and <tt>:velocity</tt> is only set if the +options+ passed in doesn't already have those keys set.
module ReverseMerge
# Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
def reverse_merge(other_hash)
diff --git a/activesupport/lib/active_support/core_ext/kernel/daemonizing.rb b/activesupport/lib/active_support/core_ext/kernel/daemonizing.rb
index 0e78819fdf..ed9d1f9bf2 100644
--- a/activesupport/lib/active_support/core_ext/kernel/daemonizing.rb
+++ b/activesupport/lib/active_support/core_ext/kernel/daemonizing.rb
@@ -2,14 +2,6 @@ module Kernel
# Turns the current script into a daemon process that detaches from the console.
# It can be shut down with a TERM signal.
def daemonize
- exit if fork # Parent exits, child continues.
- Process.setsid # Become session leader.
- exit if fork # Zap session leader. See [1].
- Dir.chdir "/" # Release old working directory.
- File.umask 0000 # Ensure sensible umask. Adjust as needed.
- STDIN.reopen "/dev/null" # Free file descriptors and
- STDOUT.reopen "/dev/null", "a" # point them somewhere sensible.
- STDERR.reopen STDOUT # STDOUT/ERR should better go to a logfile.
- trap("TERM") { exit }
+ Process.daemon
end
-end \ No newline at end of file
+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 58ff363244..51e1c9af90 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
@@ -1,6 +1,16 @@
# Extends the module object with module and instance accessors for class attributes,
# just like the native attr* accessors for instance attributes.
-class Module # :nodoc:
+#
+# module AppConfiguration
+# mattr_accessor :google_api_key
+# self.google_api_key = "123456789"
+#
+# mattr_accessor :paypal_url
+# self.paypal_url = "www.sandbox.paypal.com"
+# end
+#
+# AppConfiguration.google_api_key = "overriding the api key!"
+class Module
def mattr_reader(*syms)
syms.each do |sym|
next if sym.is_a?(Hash)
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index f6647eaed3..e0b5f3e379 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -1,8 +1,8 @@
class Module
# Provides a delegate class method to easily expose contained objects' methods
# as your own. Pass one or more methods (specified as symbols or strings)
- # and the name of the target object as the final :to option (also a symbol
- # or string). At least one method and the :to option are required.
+ # and the name of the target object as the final <tt>:to</tt> option (also a symbol
+ # or string). At least one method and the <tt>:to</tt> option are required.
#
# Delegation is particularly useful with Active Record associations:
#
@@ -20,6 +20,7 @@ class Module
# Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>
#
# Multiple delegates to the same target are allowed:
+ #
# class Foo < ActiveRecord::Base
# belongs_to :greeter
# delegate :hello, :goodbye, :to => :greeter
@@ -28,7 +29,8 @@ class Module
# Foo.new.goodbye # => "goodbye"
#
# Methods can be delegated to instance variables, class variables, or constants
- # by providing the variable as a symbol:
+ # by providing them as a symbols:
+ #
# class Foo
# CONSTANT_ARRAY = [0,1,2,3]
# @@class_array = [4,5,6,7]
diff --git a/activesupport/lib/active_support/core_ext/process.rb b/activesupport/lib/active_support/core_ext/process.rb
new file mode 100644
index 0000000000..0b0bc6dc69
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/process.rb
@@ -0,0 +1 @@
+require 'active_support/core_ext/process/daemon'
diff --git a/activesupport/lib/active_support/core_ext/process/daemon.rb b/activesupport/lib/active_support/core_ext/process/daemon.rb
new file mode 100644
index 0000000000..95ad5f8a5d
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/process/daemon.rb
@@ -0,0 +1,25 @@
+if RUBY_VERSION < "1.9"
+ module Process
+ def self.daemon(nochdir = nil, noclose = nil)
+ exit if fork # Parent exits, child continues.
+ Process.setsid # Become session leader.
+ exit if fork # Zap session leader. See [1].
+
+ unless nochdir
+ Dir.chdir "/" # Release old working directory.
+ end
+
+ File.umask 0000 # Ensure sensible umask. Adjust as needed.
+
+ unless noclose
+ STDIN.reopen "/dev/null" # Free file descriptors and
+ STDOUT.reopen "/dev/null", "a" # point them somewhere sensible.
+ STDERR.reopen '/dev/null', 'a'
+ end
+
+ trap("TERM") { exit }
+
+ return 0
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/range/include_range.rb b/activesupport/lib/active_support/core_ext/range/include_range.rb
index cd53cf154a..9a7d235695 100644
--- a/activesupport/lib/active_support/core_ext/range/include_range.rb
+++ b/activesupport/lib/active_support/core_ext/range/include_range.rb
@@ -7,6 +7,14 @@ module ActiveSupport #:nodoc:
base.alias_method_chain :include?, :range
end
+ # Extends the default Range#include? to support range comparisons.
+ # (1..5).include?(1..5) # => true
+ # (1..5).include?(2..3) # => true
+ # (1..5).include?(2..6) # => false
+ #
+ # The native Range#include? behavior is untouched.
+ # ("a".."f").include?("c") # => true
+ # (5..9).include?(11) # => false
def include_with_range?(value)
if value.is_a?(::Range)
operator = exclude_end? ? :< : :<=
diff --git a/activesupport/lib/active_support/core_ext/range/overlaps.rb b/activesupport/lib/active_support/core_ext/range/overlaps.rb
index 80ed1bba9d..43c69453e7 100644
--- a/activesupport/lib/active_support/core_ext/range/overlaps.rb
+++ b/activesupport/lib/active_support/core_ext/range/overlaps.rb
@@ -3,6 +3,9 @@ module ActiveSupport #:nodoc:
module Range #:nodoc:
# Check if Ranges overlap.
module Overlaps
+ # Compare two ranges and see if they overlap eachother
+ # (1..5).overlaps?(4..6) # => true
+ # (1..5).overlaps?(7..9) # => false
def overlaps?(other)
include?(other.first) || other.include?(first)
end
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index ffbdf37789..2cce782676 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -46,12 +46,12 @@ module ActiveSupport #:nodoc:
::DateTime.civil(year, month, day, hour, min, sec, offset)
end
- # wraps class method time_with_datetime_fallback with utc_or_local == :utc
+ # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>.
def utc_time(*args)
time_with_datetime_fallback(:utc, *args)
end
- # wraps class method time_with_datetime_fallback with utc_or_local == :local
+ # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:local</tt>.
def local_time(*args)
time_with_datetime_fallback(:local, *args)
end
@@ -78,8 +78,10 @@ module ActiveSupport #:nodoc:
)
end
- # Uses Date to provide precise Time calculations for years, months, and days. The +options+ parameter takes a hash with
- # any of these keys: :years, :months, :weeks, :days, :hours, :minutes, :seconds.
+ # Uses Date to provide precise Time calculations for years, months, and days.
+ # 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>.
def advance(options)
d = to_date.advance(options)
time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index 64b2248e28..eaba46dd9c 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -120,15 +120,26 @@ module Dependencies #:nodoc:
# We can't use defined? because it will invoke const_missing for the parent
# of the name we are checking.
names.inject(Object) do |mod, name|
- return false unless mod.const_defined? name
+ return false unless uninherited_const_defined?(mod, name)
mod.const_get name
end
return true
end
+ if Module.method(:const_defined?).arity == 1
+ # Does this module define this constant?
+ # Wrapper to accomodate changing Module#const_defined? in Ruby 1.9
+ def uninherited_const_defined?(mod, const)
+ mod.const_defined?(const)
+ end
+ else
+ def uninherited_const_defined?(mod, const) #:nodoc:
+ mod.const_defined?(const, false)
+ end
+ end
+
# Given +path+, a filesystem path to a ruby file, return an array of constant
# paths which would cause Dependencies to attempt to load this file.
- #
def loadable_constants_for_path(path, bases = load_paths)
path = $1 if path =~ /\A(.*)\.rb\Z/
expanded_path = File.expand_path(path)
@@ -237,7 +248,7 @@ module Dependencies #:nodoc:
raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
end
- raise ArgumentError, "#{from_mod} is not missing constant #{const_name}!" if from_mod.const_defined?(const_name)
+ raise ArgumentError, "#{from_mod} is not missing constant #{const_name}!" if uninherited_const_defined?(from_mod, const_name)
qualified_name = qualified_name_for from_mod, const_name
path_suffix = qualified_name.underscore
@@ -246,12 +257,12 @@ module Dependencies #:nodoc:
file_path = search_for_file(path_suffix)
if file_path && ! loaded.include?(File.expand_path(file_path)) # We found a matching file to load
require_or_load file_path
- raise LoadError, "Expected #{file_path} to define #{qualified_name}" unless from_mod.const_defined?(const_name)
+ raise LoadError, "Expected #{file_path} to define #{qualified_name}" unless uninherited_const_defined?(from_mod, const_name)
return from_mod.const_get(const_name)
elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
return mod
elsif (parent = from_mod.parent) && parent != from_mod &&
- ! from_mod.parents.any? { |p| p.const_defined?(const_name) }
+ ! from_mod.parents.any? { |p| uninherited_const_defined?(p, const_name) }
# If our parents do not have a constant named +const_name+ then we are free
# to attempt to load upwards. If they do have such a constant, then this
# const_missing must be due to from_mod::const_name, which should not
@@ -423,10 +434,12 @@ module Dependencies #:nodoc:
protected
def log_call(*args)
- arg_str = args.collect(&:inspect) * ', '
- /in `([a-z_\?\!]+)'/ =~ caller(1).first
- selector = $1 || '<unknown>'
- log "called #{selector}(#{arg_str})"
+ if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER && log_activity
+ arg_str = args.collect(&:inspect) * ', '
+ /in `([a-z_\?\!]+)'/ =~ caller(1).first
+ selector = $1 || '<unknown>'
+ log "called #{selector}(#{arg_str})"
+ end
end
def log(msg)
diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb
index 9f724619e9..c8736549f4 100644
--- a/activesupport/lib/active_support/inflector.rb
+++ b/activesupport/lib/active_support/inflector.rb
@@ -68,8 +68,9 @@ module Inflector
(@uncountables << words).flatten!
end
- # Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type,
- # the options are: :plurals, :singulars, :uncountables
+ # Clears the loaded inflections within a given scope (default is <tt>:all</tt>).
+ # Give the scope as a symbol of the inflection type, the options are: <tt>:plurals</tt>,
+ # <tt>:singulars</tt>, <tt>:uncountables</tt>.
#
# Examples:
# clear :all
@@ -245,13 +246,23 @@ module Inflector
underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
end
- # Constantize tries to find a declared constant with the name specified
- # in the string. It raises a NameError when the name is not in CamelCase
- # or is not initialized.
+ # Tries to find a constant with the name specified in the argument string:
#
- # Examples
- # "Module".constantize #=> Module
- # "Class".constantize #=> Class
+ # "Module".constantize # => Module
+ # "Test::Unit".constantize # => Test::Unit
+ #
+ # The name is assumed to be the one of a top-level constant, no matter whether
+ # it starts with "::" or not. No lexical context is taken into account:
+ #
+ # C = 'outside'
+ # module M
+ # C = 'inside'
+ # C # => 'inside'
+ # "C".constantize # => 'outside', same as ::C
+ # end
+ #
+ # NameError is raised when the name is not in CamelCase or the constant is
+ # unknown.
def constantize(camel_cased_word)
unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
diff --git a/activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb b/activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb
index 66fe47a604..0166b69ac3 100644
--- a/activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb
+++ b/activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb
@@ -284,7 +284,9 @@ module ActiveSupport::Multibyte::Handlers #:nodoc:
# passing strings to databases and validations.
#
# * <tt>str</tt> - The string to perform normalization on.
- # * <tt>form</tt> - The form you want to normalize in. Should be one of the following: :c, :kc, :d or :kd.
+ # * <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.
def normalize(str, form=ActiveSupport::Multibyte::DEFAULT_NORMALIZATION_FORM)
# See http://www.unicode.org/reports/tr15, Table 1
codepoints = u_unpack(str)
diff --git a/activesupport/lib/active_support/ordered_options.rb b/activesupport/lib/active_support/ordered_options.rb
index b2b1b0e438..3172f62f0d 100644
--- a/activesupport/lib/active_support/ordered_options.rb
+++ b/activesupport/lib/active_support/ordered_options.rb
@@ -18,6 +18,12 @@ module ActiveSupport
pair = assoc(key)
pair ? pair.last : nil
end
+
+ def delete(key)
+ pair = assoc(key)
+ pair ? array_index = index(pair) : nil
+ array_index ? delete_at(array_index).last : nil
+ end
def keys
collect { |key, value| key }
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index f1a2498298..461d52e40e 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -101,7 +101,8 @@ module ActiveSupport
end
alias_method :rfc822, :rfc2822
- # :db format outputs time in UTC; all others output time in local. Uses TimeWithZone's strftime, so %Z and %z work correctly
+ # <tt>:db</tt> format outputs time in UTC; all others output time in local.
+ # Uses TimeWithZone's +strftime+, so <tt>%Z</tt> and <tt>%z</tt> work correctly.
def to_s(format = :default)
return utc.to_s(format) if format == :db
if formatter = ::Time::DATE_FORMATS[format]
@@ -111,7 +112,7 @@ module ActiveSupport
end
end
- # Replaces %Z and %z directives with #zone and #formatted_offset, respectively, before passing to
+ # Replaces <tt>%Z</tt> and <tt>%z</tt> directives with +zone+ and +formatted_offset+, respectively, before passing to
# Time#strftime, so that zone information is correct
def strftime(format)
format = format.gsub('%Z', zone).gsub('%z', formatted_offset(false))
@@ -138,9 +139,9 @@ module ActiveSupport
result.in_time_zone(time_zone)
end
- # If a time-like object is passed in, compare it with #utc
- # Else if wrapped #time is a DateTime, use DateTime#ago instead of #-
- # Otherwise, just pass on to method missing
+ # If a time-like object is passed in, compare it with +utc+.
+ # Else if wrapped +time+ is a DateTime, use DateTime#ago instead of DateTime#-.
+ # Otherwise, just pass on to +method_missing+.
def -(other)
if other.acts_like?(:time)
utc - other
@@ -180,7 +181,7 @@ module ActiveSupport
alias_method :hash, :to_i
alias_method :tv_sec, :to_i
- # A TimeWithZone acts like a Time, so just return self
+ # A TimeWithZone acts like a Time, so just return +self+.
def to_time
self
end
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 80057fe832..9cdc2a74ed 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -1,149 +1,152 @@
class TimeZone
- # Keys are Rails TimeZone names, values are TZInfo identifiers
- MAPPING = {
- "International Date Line West" => "Pacific/Midway",
- "Midway Island" => "Pacific/Midway",
- "Samoa" => "Pacific/Pago_Pago",
- "Hawaii" => "Pacific/Honolulu",
- "Alaska" => "America/Juneau",
- "Pacific Time (US & Canada)" => "America/Los_Angeles",
- "Tijuana" => "America/Tijuana",
- "Mountain Time (US & Canada)" => "America/Denver",
- "Arizona" => "America/Phoenix",
- "Chihuahua" => "America/Chihuahua",
- "Mazatlan" => "America/Mazatlan",
- "Central Time (US & Canada)" => "America/Chicago",
- "Saskatchewan" => "America/Regina",
- "Guadalajara" => "America/Mexico_City",
- "Mexico City" => "America/Mexico_City",
- "Monterrey" => "America/Monterrey",
- "Central America" => "America/Guatemala",
- "Eastern Time (US & Canada)" => "America/New_York",
- "Indiana (East)" => "America/Indiana/Indianapolis",
- "Bogota" => "America/Bogota",
- "Lima" => "America/Lima",
- "Quito" => "America/Lima",
- "Atlantic Time (Canada)" => "America/Halifax",
- "Caracas" => "America/Caracas",
- "La Paz" => "America/La_Paz",
- "Santiago" => "America/Santiago",
- "Newfoundland" => "America/St_Johns",
- "Brasilia" => "America/Argentina/Buenos_Aires",
- "Buenos Aires" => "America/Argentina/Buenos_Aires",
- "Georgetown" => "America/Argentina/San_Juan",
- "Greenland" => "America/Godthab",
- "Mid-Atlantic" => "Atlantic/South_Georgia",
- "Azores" => "Atlantic/Azores",
- "Cape Verde Is." => "Atlantic/Cape_Verde",
- "Dublin" => "Europe/Dublin",
- "Edinburgh" => "Europe/Dublin",
- "Lisbon" => "Europe/Lisbon",
- "London" => "Europe/London",
- "Casablanca" => "Africa/Casablanca",
- "Monrovia" => "Africa/Monrovia",
- "UTC" => "Etc/UTC",
- "Belgrade" => "Europe/Belgrade",
- "Bratislava" => "Europe/Bratislava",
- "Budapest" => "Europe/Budapest",
- "Ljubljana" => "Europe/Ljubljana",
- "Prague" => "Europe/Prague",
- "Sarajevo" => "Europe/Sarajevo",
- "Skopje" => "Europe/Skopje",
- "Warsaw" => "Europe/Warsaw",
- "Zagreb" => "Europe/Zagreb",
- "Brussels" => "Europe/Brussels",
- "Copenhagen" => "Europe/Copenhagen",
- "Madrid" => "Europe/Madrid",
- "Paris" => "Europe/Paris",
- "Amsterdam" => "Europe/Amsterdam",
- "Berlin" => "Europe/Berlin",
- "Bern" => "Europe/Berlin",
- "Rome" => "Europe/Rome",
- "Stockholm" => "Europe/Stockholm",
- "Vienna" => "Europe/Vienna",
- "West Central Africa" => "Africa/Algiers",
- "Bucharest" => "Europe/Bucharest",
- "Cairo" => "Africa/Cairo",
- "Helsinki" => "Europe/Helsinki",
- "Kyev" => "Europe/Kiev",
- "Riga" => "Europe/Riga",
- "Sofia" => "Europe/Sofia",
- "Tallinn" => "Europe/Tallinn",
- "Vilnius" => "Europe/Vilnius",
- "Athens" => "Europe/Athens",
- "Istanbul" => "Europe/Istanbul",
- "Minsk" => "Europe/Minsk",
- "Jerusalem" => "Asia/Jerusalem",
- "Harare" => "Africa/Harare",
- "Pretoria" => "Africa/Johannesburg",
- "Moscow" => "Europe/Moscow",
- "St. Petersburg" => "Europe/Moscow",
- "Volgograd" => "Europe/Moscow",
- "Kuwait" => "Asia/Kuwait",
- "Riyadh" => "Asia/Riyadh",
- "Nairobi" => "Africa/Nairobi",
- "Baghdad" => "Asia/Baghdad",
- "Tehran" => "Asia/Tehran",
- "Abu Dhabi" => "Asia/Muscat",
- "Muscat" => "Asia/Muscat",
- "Baku" => "Asia/Baku",
- "Tbilisi" => "Asia/Tbilisi",
- "Yerevan" => "Asia/Yerevan",
- "Kabul" => "Asia/Kabul",
- "Ekaterinburg" => "Asia/Yekaterinburg",
- "Islamabad" => "Asia/Karachi",
- "Karachi" => "Asia/Karachi",
- "Tashkent" => "Asia/Tashkent",
- "Chennai" => "Asia/Kolkata",
- "Kolkata" => "Asia/Kolkata",
- "Mumbai" => "Asia/Kolkata",
- "New Delhi" => "Asia/Kolkata",
- "Kathmandu" => "Asia/Katmandu",
- "Astana" => "Asia/Dhaka",
- "Dhaka" => "Asia/Dhaka",
- "Sri Jayawardenepura" => "Asia/Dhaka",
- "Almaty" => "Asia/Almaty",
- "Novosibirsk" => "Asia/Novosibirsk",
- "Rangoon" => "Asia/Rangoon",
- "Bangkok" => "Asia/Bangkok",
- "Hanoi" => "Asia/Bangkok",
- "Jakarta" => "Asia/Jakarta",
- "Krasnoyarsk" => "Asia/Krasnoyarsk",
- "Beijing" => "Asia/Shanghai",
- "Chongqing" => "Asia/Chongqing",
- "Hong Kong" => "Asia/Hong_Kong",
- "Urumqi" => "Asia/Urumqi",
- "Kuala Lumpur" => "Asia/Kuala_Lumpur",
- "Singapore" => "Asia/Singapore",
- "Taipei" => "Asia/Taipei",
- "Perth" => "Australia/Perth",
- "Irkutsk" => "Asia/Irkutsk",
- "Ulaan Bataar" => "Asia/Ulaanbaatar",
- "Seoul" => "Asia/Seoul",
- "Osaka" => "Asia/Tokyo",
- "Sapporo" => "Asia/Tokyo",
- "Tokyo" => "Asia/Tokyo",
- "Yakutsk" => "Asia/Yakutsk",
- "Darwin" => "Australia/Darwin",
- "Adelaide" => "Australia/Adelaide",
- "Canberra" => "Australia/Melbourne",
- "Melbourne" => "Australia/Melbourne",
- "Sydney" => "Australia/Sydney",
- "Brisbane" => "Australia/Brisbane",
- "Hobart" => "Australia/Hobart",
- "Vladivostok" => "Asia/Vladivostok",
- "Guam" => "Pacific/Guam",
- "Port Moresby" => "Pacific/Port_Moresby",
- "Magadan" => "Asia/Magadan",
- "Solomon Is." => "Asia/Magadan",
- "New Caledonia" => "Pacific/Noumea",
- "Fiji" => "Pacific/Fiji",
- "Kamchatka" => "Asia/Kamchatka",
- "Marshall Is." => "Pacific/Majuro",
- "Auckland" => "Pacific/Auckland",
- "Wellington" => "Pacific/Auckland",
- "Nuku'alofa" => "Pacific/Tongatapu"
- }
+ unless const_defined?(:MAPPING)
+ # Keys are Rails TimeZone names, values are TZInfo identifiers
+ MAPPING = {
+ "International Date Line West" => "Pacific/Midway",
+ "Midway Island" => "Pacific/Midway",
+ "Samoa" => "Pacific/Pago_Pago",
+ "Hawaii" => "Pacific/Honolulu",
+ "Alaska" => "America/Juneau",
+ "Pacific Time (US & Canada)" => "America/Los_Angeles",
+ "Tijuana" => "America/Tijuana",
+ "Mountain Time (US & Canada)" => "America/Denver",
+ "Arizona" => "America/Phoenix",
+ "Chihuahua" => "America/Chihuahua",
+ "Mazatlan" => "America/Mazatlan",
+ "Central Time (US & Canada)" => "America/Chicago",
+ "Saskatchewan" => "America/Regina",
+ "Guadalajara" => "America/Mexico_City",
+ "Mexico City" => "America/Mexico_City",
+ "Monterrey" => "America/Monterrey",
+ "Central America" => "America/Guatemala",
+ "Eastern Time (US & Canada)" => "America/New_York",
+ "Indiana (East)" => "America/Indiana/Indianapolis",
+ "Bogota" => "America/Bogota",
+ "Lima" => "America/Lima",
+ "Quito" => "America/Lima",
+ "Atlantic Time (Canada)" => "America/Halifax",
+ "Caracas" => "America/Caracas",
+ "La Paz" => "America/La_Paz",
+ "Santiago" => "America/Santiago",
+ "Newfoundland" => "America/St_Johns",
+ "Brasilia" => "America/Argentina/Buenos_Aires",
+ "Buenos Aires" => "America/Argentina/Buenos_Aires",
+ "Georgetown" => "America/Argentina/San_Juan",
+ "Greenland" => "America/Godthab",
+ "Mid-Atlantic" => "Atlantic/South_Georgia",
+ "Azores" => "Atlantic/Azores",
+ "Cape Verde Is." => "Atlantic/Cape_Verde",
+ "Dublin" => "Europe/Dublin",
+ "Edinburgh" => "Europe/Dublin",
+ "Lisbon" => "Europe/Lisbon",
+ "London" => "Europe/London",
+ "Casablanca" => "Africa/Casablanca",
+ "Monrovia" => "Africa/Monrovia",
+ "UTC" => "Etc/UTC",
+ "Belgrade" => "Europe/Belgrade",
+ "Bratislava" => "Europe/Bratislava",
+ "Budapest" => "Europe/Budapest",
+ "Ljubljana" => "Europe/Ljubljana",
+ "Prague" => "Europe/Prague",
+ "Sarajevo" => "Europe/Sarajevo",
+ "Skopje" => "Europe/Skopje",
+ "Warsaw" => "Europe/Warsaw",
+ "Zagreb" => "Europe/Zagreb",
+ "Brussels" => "Europe/Brussels",
+ "Copenhagen" => "Europe/Copenhagen",
+ "Madrid" => "Europe/Madrid",
+ "Paris" => "Europe/Paris",
+ "Amsterdam" => "Europe/Amsterdam",
+ "Berlin" => "Europe/Berlin",
+ "Bern" => "Europe/Berlin",
+ "Rome" => "Europe/Rome",
+ "Stockholm" => "Europe/Stockholm",
+ "Vienna" => "Europe/Vienna",
+ "West Central Africa" => "Africa/Algiers",
+ "Bucharest" => "Europe/Bucharest",
+ "Cairo" => "Africa/Cairo",
+ "Helsinki" => "Europe/Helsinki",
+ "Kyev" => "Europe/Kiev",
+ "Riga" => "Europe/Riga",
+ "Sofia" => "Europe/Sofia",
+ "Tallinn" => "Europe/Tallinn",
+ "Vilnius" => "Europe/Vilnius",
+ "Athens" => "Europe/Athens",
+ "Istanbul" => "Europe/Istanbul",
+ "Minsk" => "Europe/Minsk",
+ "Jerusalem" => "Asia/Jerusalem",
+ "Harare" => "Africa/Harare",
+ "Pretoria" => "Africa/Johannesburg",
+ "Moscow" => "Europe/Moscow",
+ "St. Petersburg" => "Europe/Moscow",
+ "Volgograd" => "Europe/Moscow",
+ "Kuwait" => "Asia/Kuwait",
+ "Riyadh" => "Asia/Riyadh",
+ "Nairobi" => "Africa/Nairobi",
+ "Baghdad" => "Asia/Baghdad",
+ "Tehran" => "Asia/Tehran",
+ "Abu Dhabi" => "Asia/Muscat",
+ "Muscat" => "Asia/Muscat",
+ "Baku" => "Asia/Baku",
+ "Tbilisi" => "Asia/Tbilisi",
+ "Yerevan" => "Asia/Yerevan",
+ "Kabul" => "Asia/Kabul",
+ "Ekaterinburg" => "Asia/Yekaterinburg",
+ "Islamabad" => "Asia/Karachi",
+ "Karachi" => "Asia/Karachi",
+ "Tashkent" => "Asia/Tashkent",
+ "Chennai" => "Asia/Kolkata",
+ "Kolkata" => "Asia/Kolkata",
+ "Mumbai" => "Asia/Kolkata",
+ "New Delhi" => "Asia/Kolkata",
+ "Kathmandu" => "Asia/Katmandu",
+ "Astana" => "Asia/Dhaka",
+ "Dhaka" => "Asia/Dhaka",
+ "Sri Jayawardenepura" => "Asia/Dhaka",
+ "Almaty" => "Asia/Almaty",
+ "Novosibirsk" => "Asia/Novosibirsk",
+ "Rangoon" => "Asia/Rangoon",
+ "Bangkok" => "Asia/Bangkok",
+ "Hanoi" => "Asia/Bangkok",
+ "Jakarta" => "Asia/Jakarta",
+ "Krasnoyarsk" => "Asia/Krasnoyarsk",
+ "Beijing" => "Asia/Shanghai",
+ "Chongqing" => "Asia/Chongqing",
+ "Hong Kong" => "Asia/Hong_Kong",
+ "Urumqi" => "Asia/Urumqi",
+ "Kuala Lumpur" => "Asia/Kuala_Lumpur",
+ "Singapore" => "Asia/Singapore",
+ "Taipei" => "Asia/Taipei",
+ "Perth" => "Australia/Perth",
+ "Irkutsk" => "Asia/Irkutsk",
+ "Ulaan Bataar" => "Asia/Ulaanbaatar",
+ "Seoul" => "Asia/Seoul",
+ "Osaka" => "Asia/Tokyo",
+ "Sapporo" => "Asia/Tokyo",
+ "Tokyo" => "Asia/Tokyo",
+ "Yakutsk" => "Asia/Yakutsk",
+ "Darwin" => "Australia/Darwin",
+ "Adelaide" => "Australia/Adelaide",
+ "Canberra" => "Australia/Melbourne",
+ "Melbourne" => "Australia/Melbourne",
+ "Sydney" => "Australia/Sydney",
+ "Brisbane" => "Australia/Brisbane",
+ "Hobart" => "Australia/Hobart",
+ "Vladivostok" => "Asia/Vladivostok",
+ "Guam" => "Pacific/Guam",
+ "Port Moresby" => "Pacific/Port_Moresby",
+ "Magadan" => "Asia/Magadan",
+ "Solomon Is." => "Asia/Magadan",
+ "New Caledonia" => "Pacific/Noumea",
+ "Fiji" => "Pacific/Fiji",
+ "Kamchatka" => "Asia/Kamchatka",
+ "Marshall Is." => "Pacific/Majuro",
+ "Auckland" => "Pacific/Auckland",
+ "Wellington" => "Pacific/Auckland",
+ "Nuku'alofa" => "Pacific/Tongatapu"
+ }.each { |name, zone| name.freeze; zone.freeze }
+ MAPPING.freeze
+ end
include Comparable
attr_reader :name
@@ -157,7 +160,7 @@ class TimeZone
@utc_offset = utc_offset
@tzinfo = tzinfo
end
-
+
def utc_offset
@utc_offset ||= tzinfo.current_period.utc_offset
end
@@ -180,7 +183,7 @@ class TimeZone
def to_s
"(UTC#{formatted_offset}) #{name}"
end
-
+
# Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from given values. Example:
#
# Time.zone = "Hawaii" # => "Hawaii"
@@ -199,7 +202,7 @@ class TimeZone
utc = Time.at(secs).utc rescue DateTime.civil(1970).since(secs)
utc.in_time_zone(self)
end
-
+
# Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from parsed string. Example:
#
# Time.zone = "Hawaii" # => "Hawaii"
@@ -213,7 +216,7 @@ class TimeZone
time = Time.parse(str, now) rescue DateTime.parse(str)
ActiveSupport::TimeWithZone.new(nil, self, time)
end
-
+
# Returns an ActiveSupport::TimeWithZone instance representing the current time
# in the time zone represented by +self+. Example:
#
@@ -228,12 +231,12 @@ class TimeZone
tzinfo.now.to_date
end
- # Adjust the given time to the simultaneous time in the time zone represented by +self+. Returns a
+ # Adjust the given time to the simultaneous time in the time zone represented by +self+. Returns a
# Time.utc() instance -- if you want an ActiveSupport::TimeWithZone instance, use Time#in_time_zone() instead.
def utc_to_local(time)
tzinfo.utc_to_local(time)
end
-
+
# Adjust the given time to the simultaneous time in UTC. Returns a Time.utc() instance.
def local_to_utc(time, dst=true)
tzinfo.local_to_utc(time, dst)
@@ -248,12 +251,75 @@ class TimeZone
def period_for_local(time, dst=true)
tzinfo.period_for_local(time, dst)
end
-
+
+ # TODO: Preload instead of lazy load for thread safety
def tzinfo
@tzinfo ||= TZInfo::Timezone.get(MAPPING[name])
end
- @@zones = nil
+ unless const_defined?(:ZONES)
+ ZONES = []
+ ZONES_MAP = {}
+ [[-39_600, "International Date Line West", "Midway Island", "Samoa" ],
+ [-36_000, "Hawaii" ],
+ [-32_400, "Alaska" ],
+ [-28_800, "Pacific Time (US & Canada)", "Tijuana" ],
+ [-25_200, "Mountain Time (US & Canada)", "Chihuahua", "Mazatlan",
+ "Arizona" ],
+ [-21_600, "Central Time (US & Canada)", "Saskatchewan", "Guadalajara",
+ "Mexico City", "Monterrey", "Central America" ],
+ [-18_000, "Eastern Time (US & Canada)", "Indiana (East)", "Bogota",
+ "Lima", "Quito" ],
+ [-14_400, "Atlantic Time (Canada)", "Caracas", "La Paz", "Santiago" ],
+ [-12_600, "Newfoundland" ],
+ [-10_800, "Brasilia", "Buenos Aires", "Georgetown", "Greenland" ],
+ [ -7_200, "Mid-Atlantic" ],
+ [ -3_600, "Azores", "Cape Verde Is." ],
+ [ 0, "Dublin", "Edinburgh", "Lisbon", "London", "Casablanca",
+ "Monrovia", "UTC" ],
+ [ 3_600, "Belgrade", "Bratislava", "Budapest", "Ljubljana", "Prague",
+ "Sarajevo", "Skopje", "Warsaw", "Zagreb", "Brussels",
+ "Copenhagen", "Madrid", "Paris", "Amsterdam", "Berlin",
+ "Bern", "Rome", "Stockholm", "Vienna",
+ "West Central Africa" ],
+ [ 7_200, "Bucharest", "Cairo", "Helsinki", "Kyev", "Riga", "Sofia",
+ "Tallinn", "Vilnius", "Athens", "Istanbul", "Minsk",
+ "Jerusalem", "Harare", "Pretoria" ],
+ [ 10_800, "Moscow", "St. Petersburg", "Volgograd", "Kuwait", "Riyadh",
+ "Nairobi", "Baghdad" ],
+ [ 12_600, "Tehran" ],
+ [ 14_400, "Abu Dhabi", "Muscat", "Baku", "Tbilisi", "Yerevan" ],
+ [ 16_200, "Kabul" ],
+ [ 18_000, "Ekaterinburg", "Islamabad", "Karachi", "Tashkent" ],
+ [ 19_800, "Chennai", "Kolkata", "Mumbai", "New Delhi" ],
+ [ 20_700, "Kathmandu" ],
+ [ 21_600, "Astana", "Dhaka", "Sri Jayawardenepura", "Almaty",
+ "Novosibirsk" ],
+ [ 23_400, "Rangoon" ],
+ [ 25_200, "Bangkok", "Hanoi", "Jakarta", "Krasnoyarsk" ],
+ [ 28_800, "Beijing", "Chongqing", "Hong Kong", "Urumqi",
+ "Kuala Lumpur", "Singapore", "Taipei", "Perth", "Irkutsk",
+ "Ulaan Bataar" ],
+ [ 32_400, "Seoul", "Osaka", "Sapporo", "Tokyo", "Yakutsk" ],
+ [ 34_200, "Darwin", "Adelaide" ],
+ [ 36_000, "Canberra", "Melbourne", "Sydney", "Brisbane", "Hobart",
+ "Vladivostok", "Guam", "Port Moresby" ],
+ [ 39_600, "Magadan", "Solomon Is.", "New Caledonia" ],
+ [ 43_200, "Fiji", "Kamchatka", "Marshall Is.", "Auckland",
+ "Wellington" ],
+ [ 46_800, "Nuku'alofa" ]].
+ each do |offset, *places|
+ places.each do |place|
+ place.freeze
+ zone = new(place, offset)
+ ZONES << zone
+ ZONES_MAP[place] = zone
+ end
+ end
+ ZONES.sort!
+ ZONES.freeze
+ ZONES_MAP.freeze
+ end
class << self
alias_method :create, :new
@@ -269,67 +335,7 @@ class TimeZone
# TimeZone objects per time zone, in many cases, to make it easier
# for users to find their own time zone.
def all
- unless @@zones
- @@zones = []
- @@zones_map = {}
- [[-39_600, "International Date Line West", "Midway Island", "Samoa" ],
- [-36_000, "Hawaii" ],
- [-32_400, "Alaska" ],
- [-28_800, "Pacific Time (US & Canada)", "Tijuana" ],
- [-25_200, "Mountain Time (US & Canada)", "Chihuahua", "Mazatlan",
- "Arizona" ],
- [-21_600, "Central Time (US & Canada)", "Saskatchewan", "Guadalajara",
- "Mexico City", "Monterrey", "Central America" ],
- [-18_000, "Eastern Time (US & Canada)", "Indiana (East)", "Bogota",
- "Lima", "Quito" ],
- [-14_400, "Atlantic Time (Canada)", "Caracas", "La Paz", "Santiago" ],
- [-12_600, "Newfoundland" ],
- [-10_800, "Brasilia", "Buenos Aires", "Georgetown", "Greenland" ],
- [ -7_200, "Mid-Atlantic" ],
- [ -3_600, "Azores", "Cape Verde Is." ],
- [ 0, "Dublin", "Edinburgh", "Lisbon", "London", "Casablanca",
- "Monrovia", "UTC" ],
- [ 3_600, "Belgrade", "Bratislava", "Budapest", "Ljubljana", "Prague",
- "Sarajevo", "Skopje", "Warsaw", "Zagreb", "Brussels",
- "Copenhagen", "Madrid", "Paris", "Amsterdam", "Berlin",
- "Bern", "Rome", "Stockholm", "Vienna",
- "West Central Africa" ],
- [ 7_200, "Bucharest", "Cairo", "Helsinki", "Kyev", "Riga", "Sofia",
- "Tallinn", "Vilnius", "Athens", "Istanbul", "Minsk",
- "Jerusalem", "Harare", "Pretoria" ],
- [ 10_800, "Moscow", "St. Petersburg", "Volgograd", "Kuwait", "Riyadh",
- "Nairobi", "Baghdad" ],
- [ 12_600, "Tehran" ],
- [ 14_400, "Abu Dhabi", "Muscat", "Baku", "Tbilisi", "Yerevan" ],
- [ 16_200, "Kabul" ],
- [ 18_000, "Ekaterinburg", "Islamabad", "Karachi", "Tashkent" ],
- [ 19_800, "Chennai", "Kolkata", "Mumbai", "New Delhi" ],
- [ 20_700, "Kathmandu" ],
- [ 21_600, "Astana", "Dhaka", "Sri Jayawardenepura", "Almaty",
- "Novosibirsk" ],
- [ 23_400, "Rangoon" ],
- [ 25_200, "Bangkok", "Hanoi", "Jakarta", "Krasnoyarsk" ],
- [ 28_800, "Beijing", "Chongqing", "Hong Kong", "Urumqi",
- "Kuala Lumpur", "Singapore", "Taipei", "Perth", "Irkutsk",
- "Ulaan Bataar" ],
- [ 32_400, "Seoul", "Osaka", "Sapporo", "Tokyo", "Yakutsk" ],
- [ 34_200, "Darwin", "Adelaide" ],
- [ 36_000, "Canberra", "Melbourne", "Sydney", "Brisbane", "Hobart",
- "Vladivostok", "Guam", "Port Moresby" ],
- [ 39_600, "Magadan", "Solomon Is.", "New Caledonia" ],
- [ 43_200, "Fiji", "Kamchatka", "Marshall Is.", "Auckland",
- "Wellington" ],
- [ 46_800, "Nuku'alofa" ]].
- each do |offset, *places|
- places.each do |place|
- zone = create(place, offset)
- @@zones << zone
- @@zones_map[place] = zone
- end
- end
- @@zones.sort!
- end
- @@zones
+ ZONES
end
# Locate a specific time zone object. If the argument is a string, it
@@ -340,8 +346,7 @@ class TimeZone
def [](arg)
case arg
when String
- all # force the zones to be loaded
- @@zones_map[arg]
+ ZONES_MAP[arg]
when Numeric, ActiveSupport::Duration
arg *= 3600 if arg.abs <= 13
all.find { |z| z.utc_offset == arg.to_i }
@@ -352,7 +357,7 @@ class TimeZone
# A regular expression that matches the names of all time zones in
# the USA.
- US_ZONES = /US|Arizona|Indiana|Hawaii|Alaska/
+ US_ZONES = /US|Arizona|Indiana|Hawaii|Alaska/.freeze
# A convenience method for returning a collection of TimeZone objects
# for time zones in the USA.
diff --git a/activesupport/lib/active_support/vendor/memcache-client-1.5.0/memcache.rb b/activesupport/lib/active_support/vendor/memcache-client-1.5.0/memcache.rb
index 375cfb1430..dda7f2c30e 100644
--- a/activesupport/lib/active_support/vendor/memcache-client-1.5.0/memcache.rb
+++ b/activesupport/lib/active_support/vendor/memcache-client-1.5.0/memcache.rb
@@ -278,12 +278,12 @@ class MemCache
results = {}
- server_keys.each do |server, keys|
- keys = keys.join ' '
+ server_keys.each do |server, keys_for_server|
+ keys_for_server = keys_for_server.join ' '
values = if @multithread then
- threadsafe_cache_get_multi server, keys
+ threadsafe_cache_get_multi server, keys_for_server
else
- cache_get_multi server, keys
+ cache_get_multi server, keys_for_server
end
values.each do |key, value|
results[cache_keys[key]] = Marshal.load value
diff --git a/activesupport/lib/active_support/whiny_nil.rb b/activesupport/lib/active_support/whiny_nil.rb
index 099619191c..36fe9510ba 100644
--- a/activesupport/lib/active_support/whiny_nil.rb
+++ b/activesupport/lib/active_support/whiny_nil.rb
@@ -28,12 +28,12 @@ class NilClass
WHINERS = [::Array]
WHINERS << ::ActiveRecord::Base if defined? ::ActiveRecord
- @@method_class_map = Hash.new
+ METHOD_CLASS_MAP = Hash.new
WHINERS.each do |klass|
methods = klass.public_instance_methods - public_instance_methods
class_name = klass.name
- methods.each { |method| @@method_class_map[method.to_sym] = class_name }
+ methods.each { |method| METHOD_CLASS_MAP[method.to_sym] = class_name }
end
# Raises a RuntimeError when you attempt to call +id+ on +nil+.
@@ -43,7 +43,7 @@ class NilClass
private
def method_missing(method, *args, &block)
- raise_nil_warning_for @@method_class_map[method], method, caller
+ raise_nil_warning_for METHOD_CLASS_MAP[method], method, caller
end
# Raises a NoMethodError when you attempt to call a method on +nil+.
diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb
index 00d8f45028..26af245ff7 100644
--- a/activesupport/test/inflector_test.rb
+++ b/activesupport/test/inflector_test.rb
@@ -120,14 +120,8 @@ class InflectorTest < Test::Unit::TestCase
assert_raises(NameError) { Inflector.constantize("InvalidClass\n") }
end
- if RUBY_VERSION < '1.9.0'
- def test_constantize_does_lexical_lookup
- assert_raises(NameError) { Inflector.constantize("Ace::Base::InflectorTest") }
- end
- else
- def test_constantize_does_dynamic_lookup
- assert_equal self.class, Inflector.constantize("Ace::Base::InflectorTest")
- end
+ def test_constantize_does_lexical_lookup
+ assert_raises(NameError) { Inflector.constantize("Ace::Base::InflectorTest") }
end
def test_ordinal
diff --git a/activesupport/test/ordered_options_test.rb b/activesupport/test/ordered_options_test.rb
index 1a1d0c7648..3d537a0ae4 100644
--- a/activesupport/test/ordered_options_test.rb
+++ b/activesupport/test/ordered_options_test.rb
@@ -29,6 +29,19 @@ class OrderedHashTest < Test::Unit::TestCase
assert_equal value, @ordered_hash.values.last
assert_equal value, @ordered_hash[key]
end
+
+ def test_delete
+ key, value = 'white', 'ffffff'
+ bad_key = 'black'
+
+ @ordered_hash[key] = value
+ assert_equal @keys.length + 1, @ordered_hash.length
+
+ assert_equal value, @ordered_hash.delete(key)
+ assert_equal @keys.length, @ordered_hash.length
+
+ assert_nil @ordered_hash.delete(bad_key)
+ end
end
class OrderedOptionsTest < Test::Unit::TestCase