aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib')
-rw-r--r--activesupport/lib/active_support/core_ext/array.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/array/prepend_and_append.rb7
-rw-r--r--activesupport/lib/active_support/core_ext/io.rb15
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb55
-rw-r--r--activesupport/lib/active_support/core_ext/object.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/object/public_send.rb25
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb1
-rw-r--r--activesupport/lib/active_support/gzip.rb1
-rw-r--r--activesupport/lib/active_support/inflections.rb1
-rw-r--r--activesupport/lib/active_support/notifications.rb2
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb34
11 files changed, 114 insertions, 29 deletions
diff --git a/activesupport/lib/active_support/core_ext/array.rb b/activesupport/lib/active_support/core_ext/array.rb
index 4688468a8f..268c9bed4c 100644
--- a/activesupport/lib/active_support/core_ext/array.rb
+++ b/activesupport/lib/active_support/core_ext/array.rb
@@ -5,3 +5,4 @@ require 'active_support/core_ext/array/conversions'
require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/array/grouping'
require 'active_support/core_ext/array/random_access'
+require 'active_support/core_ext/array/prepend_and_append'
diff --git a/activesupport/lib/active_support/core_ext/array/prepend_and_append.rb b/activesupport/lib/active_support/core_ext/array/prepend_and_append.rb
new file mode 100644
index 0000000000..27718f19d4
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/array/prepend_and_append.rb
@@ -0,0 +1,7 @@
+class Array
+ # The human way of thinking about adding stuff to the end of a list is with append
+ alias_method :append, :<<
+
+ # The human way of thinking about adding stuff to the beginning of a list is with prepend
+ alias_method :prepend, :unshift
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/core_ext/io.rb b/activesupport/lib/active_support/core_ext/io.rb
new file mode 100644
index 0000000000..75f1055191
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/io.rb
@@ -0,0 +1,15 @@
+if RUBY_VERSION < '1.9.2'
+
+# :stopdoc:
+class IO
+ def self.binread(name, length = nil, offset = nil)
+ return File.read name unless length || offset
+ File.open(name, 'rb') { |f|
+ f.seek offset if offset
+ f.read length
+ }
+ end
+end
+# :startdoc:
+
+end
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index 149b849b12..8350753f78 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -1,3 +1,6 @@
+require 'active_support/core_ext/object/public_send'
+require 'active_support/core_ext/string/starts_ends_with'
+
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)
@@ -106,35 +109,49 @@ class Module
unless options.is_a?(Hash) && to = options[:to]
raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)."
end
+ prefix, to, allow_nil = options[:prefix], options[:to], options[:allow_nil]
- if options[:prefix] == true && options[:to].to_s =~ /^[^a-z_]/
+ if prefix == true && to.to_s =~ /^[^a-z_]/
raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
end
- prefix = options[:prefix] ? "#{options[:prefix] == true ? to : options[:prefix]}_" : ''
+ method_prefix =
+ if prefix
+ "#{prefix == true ? to : prefix}_"
+ else
+ ''
+ end
file, line = caller.first.split(':', 2)
line = line.to_i
methods.each do |method|
- on_nil =
- if options[:allow_nil]
- 'return'
- else
- %(raise "#{self}##{prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
- end
+ method = method.to_s
+ call = method.ends_with?('=') ? "public_send(:#{method}, " : "#{method}("
+
+ if allow_nil
+ module_eval(<<-EOS, file, line - 2)
+ def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block)
+ if #{to} || #{to}.respond_to?(:#{method}) # if client || client.respond_to?(:name)
+ #{to}.#{call}*args, &block) # client.name(*args, &block)
+ end # end
+ end # end
+ EOS
+ else
+ exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
- module_eval(<<-EOS, file, line - 5)
- def #{prefix}#{method}(*args, &block) # def customer_name(*args, &block)
- #{to}.__send__(#{method.inspect}, *args, &block) # client.__send__(:name, *args, &block)
- rescue NoMethodError # rescue NoMethodError
- if #{to}.nil? # if client.nil?
- #{on_nil} # return # depends on :allow_nil
- else # else
- raise # raise
- end # end
- end # end
- EOS
+ module_eval(<<-EOS, file, line - 1)
+ def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block)
+ #{to}.#{call}*args, &block) # client.name(*args, &block)
+ rescue NoMethodError # rescue NoMethodError
+ if #{to}.nil? # if client.nil?
+ #{exception} # # add helpful message to the exception
+ else # else
+ raise # raise
+ end # end
+ end # end
+ EOS
+ end
end
end
end
diff --git a/activesupport/lib/active_support/core_ext/object.rb b/activesupport/lib/active_support/core_ext/object.rb
index 9ad1e12699..249c2e93c5 100644
--- a/activesupport/lib/active_support/core_ext/object.rb
+++ b/activesupport/lib/active_support/core_ext/object.rb
@@ -3,6 +3,7 @@ require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/duplicable'
require 'active_support/core_ext/object/try'
require 'active_support/core_ext/object/inclusion'
+require 'active_support/core_ext/object/public_send'
require 'active_support/core_ext/object/conversions'
require 'active_support/core_ext/object/instance_variables'
diff --git a/activesupport/lib/active_support/core_ext/object/public_send.rb b/activesupport/lib/active_support/core_ext/object/public_send.rb
new file mode 100644
index 0000000000..2e77a22c4b
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/object/public_send.rb
@@ -0,0 +1,25 @@
+require 'active_support/core_ext/kernel/singleton_class'
+
+class Object
+ unless Object.public_method_defined?(:public_send)
+ # Backports Object#public_send from 1.9
+ def public_send(method, *args, &block)
+ # Don't create a singleton class for the object if it doesn't already have one
+ # (This also protects us from classes like Fixnum and Symbol, which cannot have a
+ # singleton class.)
+ klass = singleton_methods.any? ? self.singleton_class : self.class
+
+ if klass.public_method_defined?(method)
+ send(method, *args, &block)
+ else
+ if klass.private_method_defined?(method)
+ raise NoMethodError, "private method `#{method}' called for #{inspect}"
+ elsif klass.protected_method_defined?(method)
+ raise NoMethodError, "protected method `#{method}' called for #{inspect}"
+ else
+ raise NoMethodError, "undefined method `#{method}' for #{inspect}"
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index c5fbbcf890..a15a06d0e4 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -1,5 +1,6 @@
require 'active_support/duration'
require 'active_support/core_ext/time/zones'
+require 'active_support/core_ext/time/conversions'
class Time
COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
diff --git a/activesupport/lib/active_support/gzip.rb b/activesupport/lib/active_support/gzip.rb
index 62f9c9aa2e..9651f02c73 100644
--- a/activesupport/lib/active_support/gzip.rb
+++ b/activesupport/lib/active_support/gzip.rb
@@ -1,5 +1,6 @@
require 'zlib'
require 'stringio'
+require 'active_support/core_ext/string/encoding'
module ActiveSupport
# A convenient wrapper for the zlib standard library that allows compression/decompression of strings with gzip.
diff --git a/activesupport/lib/active_support/inflections.rb b/activesupport/lib/active_support/inflections.rb
index 06ceccdb22..daf2a1e1d9 100644
--- a/activesupport/lib/active_support/inflections.rb
+++ b/activesupport/lib/active_support/inflections.rb
@@ -54,6 +54,7 @@ module ActiveSupport
inflect.irregular('sex', 'sexes')
inflect.irregular('move', 'moves')
inflect.irregular('cow', 'kine')
+ inflect.irregular('zombie', 'zombies')
inflect.uncountable(%w(equipment information rice money species series fish sheep jeans))
end
diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb
index 77696eb1db..b5a70d5933 100644
--- a/activesupport/lib/active_support/notifications.rb
+++ b/activesupport/lib/active_support/notifications.rb
@@ -1,5 +1,3 @@
-require 'active_support/core_ext/module/delegation'
-
module ActiveSupport
# Notifications provides an instrumentation API for Ruby. To instrument an
# action in Ruby you just need to do:
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 728921a069..4fb487ade1 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -195,12 +195,8 @@ module ActiveSupport
# (GMT). Seconds were chosen as the offset unit because that is the unit that
# Ruby uses to represent time zone offsets (see Time#utc_offset).
def initialize(name, utc_offset = nil, tzinfo = nil)
- begin
- require 'tzinfo'
- rescue LoadError => e
- $stderr.puts "You don't have tzinfo installed in your application. Please add it to your Gemfile and run bundle install"
- raise e
- end
+ self.class.send(:require_tzinfo)
+
@name = name
@utc_offset = utc_offset
@tzinfo = tzinfo || TimeZone.find_tzinfo(name)
@@ -337,7 +333,12 @@ module ActiveSupport
end
def zones_map
- @zones_map ||= Hash[MAPPING.map { |place, _| [place, create(place)] }]
+ @zones_map ||= begin
+ new_zones_names = MAPPING.keys - lazy_zones_map.keys
+ new_zones = Hash[new_zones_names.map { |place| [place, create(place)] }]
+
+ lazy_zones_map.merge(new_zones)
+ end
end
# Locate a specific time zone object. If the argument is a string, it
@@ -349,7 +350,7 @@ module ActiveSupport
case arg
when String
begin
- zones_map[arg] ||= lookup(arg).tap { |tz| tz.utc_offset }
+ lazy_zones_map[arg] ||= lookup(arg).tap { |tz| tz.utc_offset }
rescue TZInfo::InvalidTimezoneIdentifier
nil
end
@@ -367,11 +368,28 @@ module ActiveSupport
@us_zones ||= all.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ }
end
+ protected
+
+ def require_tzinfo
+ require 'tzinfo'
+ rescue LoadError
+ $stderr.puts "You don't have tzinfo installed in your application. Please add it to your Gemfile and run bundle install"
+ raise
+ end
+
private
def lookup(name)
(tzinfo = find_tzinfo(name)) && create(tzinfo.name.freeze)
end
+
+ def lazy_zones_map
+ require_tzinfo
+
+ @lazy_zones_map ||= Hash.new do |hash, place|
+ hash[place] = create(place) if MAPPING.has_key?(place)
+ end
+ end
end
end
end