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/file_store.rb1
-rw-r--r--activesupport/lib/active_support/cache/mem_cache_store.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/calculations.rb9
-rw-r--r--activesupport/lib/active_support/core_ext/marshal.rb21
-rw-r--r--activesupport/lib/active_support/core_ext/string/multibyte.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb9
-rw-r--r--activesupport/lib/active_support/dependencies.rb76
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb27
8 files changed, 103 insertions, 52 deletions
diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb
index 2c1ad60d44..8e265ad863 100644
--- a/activesupport/lib/active_support/cache/file_store.rb
+++ b/activesupport/lib/active_support/cache/file_store.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/marshal'
require 'active_support/core_ext/file/atomic'
require 'active_support/core_ext/string/conversions'
require 'uri/common'
diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb
index 17450fe4d0..712db2c75a 100644
--- a/activesupport/lib/active_support/cache/mem_cache_store.rb
+++ b/activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -6,6 +6,7 @@ rescue LoadError => e
end
require 'digest/md5'
+require 'active_support/core_ext/marshal'
module ActiveSupport
module Cache
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 0c6437b02b..f77d444479 100644
--- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb
@@ -32,6 +32,15 @@ class DateTime
sec + (min * 60) + (hour * 3600)
end
+ # Returns the number of seconds until 23:59:59.
+ #
+ # DateTime.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399
+ # DateTime.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
+ # DateTime.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
+ def seconds_until_end_of_day
+ end_of_day.to_i - to_i
+ end
+
# Returns a new DateTime where one or more of the elements have been changed
# according to the +options+ parameter. The time options (<tt>:hour</tt>,
# <tt>:minute</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
diff --git a/activesupport/lib/active_support/core_ext/marshal.rb b/activesupport/lib/active_support/core_ext/marshal.rb
new file mode 100644
index 0000000000..fec3051c0c
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/marshal.rb
@@ -0,0 +1,21 @@
+module Marshal
+ class << self
+ def load_with_autoloading(source)
+ begin
+ load_without_autoloading(source)
+ rescue ArgumentError, NameError => exc
+ 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
+ source.rewind if source.respond_to?(:rewind)
+ retry
+ else
+ raise exc
+ end
+ end
+ end
+
+ alias_method_chain :load, :autoloading
+ end
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/core_ext/string/multibyte.rb b/activesupport/lib/active_support/core_ext/string/multibyte.rb
index 4e7824ad74..a124202936 100644
--- a/activesupport/lib/active_support/core_ext/string/multibyte.rb
+++ b/activesupport/lib/active_support/core_ext/string/multibyte.rb
@@ -6,7 +6,7 @@ class String
#
# +mb_chars+ is a multibyte safe proxy for string methods.
#
- # In Ruby 1.8 and older it creates and returns an instance of the ActiveSupport::Multibyte::Chars class which
+ # It creates and returns an instance of the ActiveSupport::Multibyte::Chars class which
# encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
# class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
#
@@ -17,9 +17,6 @@ class String
# name.mb_chars.reverse.to_s # => "rellüM sualC"
# name.mb_chars.length # => 12
#
- # In Ruby 1.9 and newer +mb_chars+ returns +self+ because String is (mostly) encoding aware. This means that
- # it becomes easy to run one version of your code on multiple Ruby versions.
- #
# == Method chaining
#
# All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
@@ -36,11 +33,7 @@ class String
# For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
# information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
def mb_chars
- if ActiveSupport::Multibyte.proxy_class.consumes?(self)
- ActiveSupport::Multibyte.proxy_class.new(self)
- else
- self
- end
+ ActiveSupport::Multibyte.proxy_class.new(self)
end
def is_utf8?
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index 931851d40e..46c9f05c15 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -62,6 +62,15 @@ class Time
to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
end
+ # Returns the number of seconds until 23:59:59.
+ #
+ # Time.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399
+ # Time.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
+ # Time.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
+ def seconds_until_end_of_day
+ end_of_day.to_i - to_i
+ end
+
# Returns a new Time where one or more of the elements have been changed according
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
# <tt>:sec</tt>, <tt>:usec</tt>) reset cascadingly, so if only the hour is passed,
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index c75fb46263..b816ecae5a 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -644,46 +644,58 @@ module ActiveSupport #:nodoc:
normalized = const.to_s.sub(/\A::/, '')
normalized.sub!(/\A(Object::)+/, '')
- constants = normalized.split('::')
- to_remove = constants.pop
- parent_name = constants.empty? ? 'Object' : constants.join('::')
+ constants = normalized.split('::')
+ to_remove = constants.pop
- if parent = safe_constantize(parent_name)
- log "removing constant #{const}"
-
- # In an autoloaded user.rb like this
- #
- # autoload :Foo, 'foo'
- #
- # class User < ActiveRecord::Base
- # end
- #
- # we correctly register "Foo" as being autoloaded. But if the app does
- # not use the "Foo" constant we need to be careful not to trigger
- # loading "foo.rb" ourselves. While #const_defined? and #const_get? do
- # require the file, #autoload? and #remove_const don't.
+ if constants.empty?
+ parent = Object
+ else
+ # This method is robust to non-reachable constants.
#
- # We are going to remove the constant nonetheless ---which exists as
- # far as Ruby is concerned--- because if the user removes the macro
- # call from a class or module that were not autoloaded, as in the
- # example above with Object, accessing to that constant must err.
- unless parent.autoload?(to_remove)
- begin
- constantized = parent.const_get(to_remove, false)
- rescue NameError
- log "the constant #{const} is not reachable anymore, skipping"
- return
- else
- constantized.before_remove_const if constantized.respond_to?(:before_remove_const)
- end
- end
+ # Non-reachable constants may be passed if some of the parents were
+ # autoloaded and already removed. It is easier to do a sanity check
+ # here than require the caller to be clever. We check the parent
+ # rather than the very const argument because we do not want to
+ # trigger Kernel#autoloads, see the comment below.
+ parent_name = constants.join('::')
+ return unless qualified_const_defined?(parent_name)
+ parent = constantize(parent_name)
+ end
+ log "removing constant #{const}"
+
+ # In an autoloaded user.rb like this
+ #
+ # autoload :Foo, 'foo'
+ #
+ # class User < ActiveRecord::Base
+ # end
+ #
+ # we correctly register "Foo" as being autoloaded. But if the app does
+ # not use the "Foo" constant we need to be careful not to trigger
+ # loading "foo.rb" ourselves. While #const_defined? and #const_get? do
+ # require the file, #autoload? and #remove_const don't.
+ #
+ # We are going to remove the constant nonetheless ---which exists as
+ # far as Ruby is concerned--- because if the user removes the macro
+ # call from a class or module that were not autoloaded, as in the
+ # example above with Object, accessing to that constant must err.
+ unless parent.autoload?(to_remove)
begin
- parent.instance_eval { remove_const to_remove }
+ constantized = parent.const_get(to_remove, false)
rescue NameError
log "the constant #{const} is not reachable anymore, skipping"
+ return
+ else
+ constantized.before_remove_const if constantized.respond_to?(:before_remove_const)
end
end
+
+ begin
+ parent.instance_eval { remove_const to_remove }
+ rescue NameError
+ log "the constant #{const} is not reachable anymore, skipping"
+ end
end
protected
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 0207f53238..1a37d6f2a4 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -278,18 +278,23 @@ module ActiveSupport
# Time.zone.now # => Fri, 31 Dec 1999 14:00:00 HST -10:00
# Time.zone.parse('22:30:00') # => Fri, 31 Dec 1999 22:30:00 HST -10:00
def parse(str, now=now)
- date_parts = Date._parse(str)
- return if date_parts.empty?
- time = Time.parse(str, now) rescue DateTime.parse(str)
-
- if date_parts[:offset].nil?
- if date_parts[:hour] && time.hour != date_parts[:hour]
- time = DateTime.parse(str)
- end
-
- ActiveSupport::TimeWithZone.new(nil, self, time)
+ parts = Date._parse(str, false)
+ return if parts.empty?
+
+ time = Time.new(
+ parts.fetch(:year, now.year),
+ parts.fetch(:mon, now.month),
+ parts.fetch(:mday, now.day),
+ parts.fetch(:hour, now.hour),
+ parts.fetch(:min, now.min),
+ parts.fetch(:sec, now.sec) + parts.fetch(:sec_fraction, 0),
+ parts.fetch(:offset, 0)
+ )
+
+ if parts[:offset]
+ TimeWithZone.new(time.utc, self)
else
- time.in_time_zone(self)
+ TimeWithZone.new(nil, self, time)
end
end