aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/core_ext
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib/active_support/core_ext')
-rw-r--r--activesupport/lib/active_support/core_ext/array/access.rb20
-rw-r--r--activesupport/lib/active_support/core_ext/array/conversions.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/array/grouping.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/date/behavior.rb16
-rw-r--r--activesupport/lib/active_support/core_ext/duplicable.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/file.rb24
-rw-r--r--activesupport/lib/active_support/core_ext/file/atomic.rb46
-rw-r--r--activesupport/lib/active_support/core_ext/hash.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/hash/deep_merge.rb23
-rw-r--r--activesupport/lib/active_support/core_ext/hash/except.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/hash/reverse_merge.rb17
-rw-r--r--activesupport/lib/active_support/core_ext/hash/slice.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/kernel/debugger.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/object.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/object/metaclass.rb13
-rw-r--r--activesupport/lib/active_support/core_ext/string/inflections.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/time/conversions.rb1
19 files changed, 161 insertions, 53 deletions
diff --git a/activesupport/lib/active_support/core_ext/array/access.rb b/activesupport/lib/active_support/core_ext/array/access.rb
index 4ac95efdc7..779ca40aea 100644
--- a/activesupport/lib/active_support/core_ext/array/access.rb
+++ b/activesupport/lib/active_support/core_ext/array/access.rb
@@ -8,6 +8,7 @@ module ActiveSupport #:nodoc:
# %w( a b c d ).from(0) # => %w( a b c d )
# %w( a b c d ).from(2) # => %w( c d )
# %w( a b c d ).from(10) # => nil
+ # %w().from(0) # => nil
def from(position)
self[position..-1]
end
@@ -17,51 +18,52 @@ module ActiveSupport #:nodoc:
# %w( a b c d ).to(0) # => %w( a )
# %w( a b c d ).to(2) # => %w( a b c )
# %w( a b c d ).to(10) # => %w( a b c d )
+ # %w().to(0) # => %w()
def to(position)
self[0..position]
end
- # Equal to self[1]
+ # Equals to <tt>self[1]</tt>.
def second
self[1]
end
- # Equal to self[2]
+ # Equals to <tt>self[2]</tt>.
def third
self[2]
end
- # Equal to self[3]
+ # Equals to <tt>self[3]</tt>.
def fourth
self[3]
end
- # Equal to self[4]
+ # Equals to <tt>self[4]</tt>.
def fifth
self[4]
end
- # Equal to self[5]
+ # Equals to <tt>self[5]</tt>.
def sixth
self[5]
end
- # Equal to self[6]
+ # Equals to <tt>self[6]</tt>.
def seventh
self[6]
end
- # Equal to self[7]
+ # Equals to <tt>self[7]</tt>.
def eighth
self[7]
end
- # Equal to self[8]
+ # Equals to <tt>self[8]</tt>.
def ninth
self[8]
end
- # Equal to self[9]
+ # Equals to <tt>self[9]</tt>.
def tenth
self[9]
end
diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb
index 49ada8f174..e67b719ddb 100644
--- a/activesupport/lib/active_support/core_ext/array/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/array/conversions.rb
@@ -6,10 +6,12 @@ module ActiveSupport #:nodoc:
module Conversions
# Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:
# * <tt>:connector</tt> - The word used to join the last element in arrays with two or more elements (default: "and")
- # * <tt>:skip_last_comma</tt> - Set to true to return "a, b and c" instead of "a, b, and c".
- def to_sentence(options = {})
- options.assert_valid_keys(:connector, :skip_last_comma)
- options.reverse_merge! :connector => 'and', :skip_last_comma => false
+ # * <tt>:skip_last_comma</tt> - Set to true to return "a, b and c" instead of "a, b, and c".
+ def to_sentence(options = {})
+ options.assert_valid_keys(:connector, :skip_last_comma, :locale)
+
+ default = I18n.translate(:'support.array.sentence_connector', :locale => options[:locale])
+ options.reverse_merge! :connector => default, :skip_last_comma => false
options[:connector] = "#{options[:connector]} " unless options[:connector].nil? || options[:connector].strip == ''
case length
@@ -23,6 +25,7 @@ module ActiveSupport #:nodoc:
"#{self[0...-1].join(', ')}#{options[:skip_last_comma] ? '' : ','} #{options[:connector]}#{self[-1]}"
end
end
+
# Calls <tt>to_param</tt> on all its elements and joins the result with
# slashes. This is used by <tt>url_for</tt> in Action Pack.
diff --git a/activesupport/lib/active_support/core_ext/array/grouping.rb b/activesupport/lib/active_support/core_ext/array/grouping.rb
index df37afb053..dd1484f8fa 100644
--- a/activesupport/lib/active_support/core_ext/array/grouping.rb
+++ b/activesupport/lib/active_support/core_ext/array/grouping.rb
@@ -19,7 +19,7 @@ module ActiveSupport #:nodoc:
# %w(1 2 3).in_groups_of(2, false) {|g| p g}
# ["1", "2"]
# ["3"]
- def in_groups_of(number, fill_with = nil, &block)
+ def in_groups_of(number, fill_with = nil)
if fill_with == false
collection = self
else
@@ -31,7 +31,7 @@ module ActiveSupport #:nodoc:
end
if block_given?
- collection.each_slice(number, &block)
+ collection.each_slice(number) { |slice| yield(slice) }
else
returning [] do |groups|
collection.each_slice(number) { |group| groups << group }
@@ -87,11 +87,11 @@ module ActiveSupport #:nodoc:
#
# [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
# (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
- def split(value = nil, &block)
- block ||= Proc.new { |e| e == value }
+ def split(value = nil)
+ using_block = block_given?
inject([[]]) do |results, element|
- if block.call(element)
+ if (using_block && yield(element)) || (value == element)
results << []
else
results.last << element
diff --git a/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb b/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb
index d2b01b1b8d..94c7c779f7 100644
--- a/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/bigdecimal/conversions.rb
@@ -21,7 +21,7 @@ module ActiveSupport #:nodoc:
# This emits the number without any scientific notation.
# I prefer it to using self.to_f.to_s, which would lose precision.
#
- # Note that YAML allows that when reconsituting floats
+ # Note that YAML allows that when reconstituting floats
# to native types, some precision may get lost.
# There is no full precision real YAML tag that I am aware of.
str = self.to_s
diff --git a/activesupport/lib/active_support/core_ext/date/behavior.rb b/activesupport/lib/active_support/core_ext/date/behavior.rb
index 011cc17cbf..6f8f7c6a82 100644
--- a/activesupport/lib/active_support/core_ext/date/behavior.rb
+++ b/activesupport/lib/active_support/core_ext/date/behavior.rb
@@ -7,6 +7,22 @@ module ActiveSupport #:nodoc:
def acts_like_date?
true
end
+
+ # Date memoizes some instance methods using metaprogramming to wrap
+ # the methods with one that caches the result in an instance variable.
+ # If a Date is frozen but the memoized method hasn't been called, the
+ # first call will result in a frozen object error since the memo
+ # instance variable is uninitialized. Work around by eagerly memoizing
+ # before freezing.
+ def freeze #:nodoc:
+ self.class.private_instance_methods(false).each do |m|
+ if m.to_s =~ /\A__\d+__\Z/
+ instance_variable_set(:"@#{m}", [send(m)])
+ end
+ end
+
+ super
+ end
end
end
end
diff --git a/activesupport/lib/active_support/core_ext/duplicable.rb b/activesupport/lib/active_support/core_ext/duplicable.rb
index adbbfd8c60..8f49ddfd9e 100644
--- a/activesupport/lib/active_support/core_ext/duplicable.rb
+++ b/activesupport/lib/active_support/core_ext/duplicable.rb
@@ -35,3 +35,9 @@ class Numeric #:nodoc:
false
end
end
+
+class Class #:nodoc:
+ def duplicable?
+ false
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/file.rb b/activesupport/lib/active_support/core_ext/file.rb
index 45d93b220f..e03f8ac44e 100644
--- a/activesupport/lib/active_support/core_ext/file.rb
+++ b/activesupport/lib/active_support/core_ext/file.rb
@@ -1,21 +1,5 @@
-require 'tempfile'
+require 'active_support/core_ext/file/atomic'
-# Write to a file atomically. Useful for situations where you don't
-# want other processes or threads to see half-written files.
-#
-# File.atomic_write("important.file") do |file|
-# file.write("hello")
-# end
-#
-# If your temp directory is not on the same filesystem as the file you're
-# trying to write, you can provide a different temporary directory.
-#
-# File.atomic_write("/data/something.important", "/data/tmp") do |f|
-# file.write("hello")
-# end
-def File.atomic_write(file_name, temp_dir = Dir.tmpdir)
- temp_file = Tempfile.new(File.basename(file_name), temp_dir)
- yield temp_file
- temp_file.close
- File.rename(temp_file.path, file_name)
-end \ No newline at end of file
+class File #:nodoc:
+ extend ActiveSupport::CoreExtensions::File::Atomic
+end
diff --git a/activesupport/lib/active_support/core_ext/file/atomic.rb b/activesupport/lib/active_support/core_ext/file/atomic.rb
new file mode 100644
index 0000000000..4d3cf5423f
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/file/atomic.rb
@@ -0,0 +1,46 @@
+require 'tempfile'
+
+module ActiveSupport #:nodoc:
+ module CoreExtensions #:nodoc:
+ module File #:nodoc:
+ module Atomic
+ # Write to a file atomically. Useful for situations where you don't
+ # want other processes or threads to see half-written files.
+ #
+ # File.atomic_write("important.file") do |file|
+ # file.write("hello")
+ # end
+ #
+ # If your temp directory is not on the same filesystem as the file you're
+ # trying to write, you can provide a different temporary directory.
+ #
+ # File.atomic_write("/data/something.important", "/data/tmp") do |f|
+ # file.write("hello")
+ # end
+ def atomic_write(file_name, temp_dir = Dir.tmpdir)
+ temp_file = Tempfile.new(basename(file_name), temp_dir)
+ yield temp_file
+ temp_file.close
+
+ begin
+ # Get original file permissions
+ old_stat = stat(file_name)
+ rescue Errno::ENOENT
+ # No old permissions, write a temp file to determine the defaults
+ check_name = ".permissions_check.#{Thread.current.object_id}.#{Process.pid}.#{rand(1000000)}"
+ new(check_name, "w")
+ old_stat = stat(check_name)
+ unlink(check_name)
+ end
+
+ # Overwrite original file with temp file
+ rename(temp_file.path, file_name)
+
+ # Set correct permissions on new file
+ chown(old_stat.uid, old_stat.gid, file_name)
+ chmod(old_stat.mode, file_name)
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/hash.rb b/activesupport/lib/active_support/core_ext/hash.rb
index 6cbd9dd378..a6065ab48e 100644
--- a/activesupport/lib/active_support/core_ext/hash.rb
+++ b/activesupport/lib/active_support/core_ext/hash.rb
@@ -1,10 +1,11 @@
-%w(keys indifferent_access reverse_merge conversions diff slice except).each do |ext|
+%w(keys indifferent_access deep_merge reverse_merge conversions diff slice except).each do |ext|
require "active_support/core_ext/hash/#{ext}"
end
class Hash #:nodoc:
include ActiveSupport::CoreExtensions::Hash::Keys
include ActiveSupport::CoreExtensions::Hash::IndifferentAccess
+ include ActiveSupport::CoreExtensions::Hash::DeepMerge
include ActiveSupport::CoreExtensions::Hash::ReverseMerge
include ActiveSupport::CoreExtensions::Hash::Conversions
include ActiveSupport::CoreExtensions::Hash::Diff
diff --git a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
new file mode 100644
index 0000000000..f8842ba57a
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
@@ -0,0 +1,23 @@
+module ActiveSupport #:nodoc:
+ module CoreExtensions #:nodoc:
+ module Hash #:nodoc:
+ # Allows for deep merging
+ module DeepMerge
+ # Returns a new hash with +self+ and +other_hash+ merged recursively.
+ def deep_merge(other_hash)
+ self.merge(other_hash) do |key, oldval, newval|
+ oldval = oldval.to_hash if oldval.respond_to?(:to_hash)
+ newval = newval.to_hash if newval.respond_to?(:to_hash)
+ oldval.class.to_s == 'Hash' && newval.class.to_s == 'Hash' ? oldval.deep_merge(newval) : newval
+ end
+ end
+
+ # Returns a new hash with +self+ and +other_hash+ merged recursively.
+ # Modifies the receiver in place.
+ def deep_merge!(other_hash)
+ replace(deep_merge(other_hash))
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/hash/except.rb b/activesupport/lib/active_support/core_ext/hash/except.rb
index bc97fa35a6..f26d01553d 100644
--- a/activesupport/lib/active_support/core_ext/hash/except.rb
+++ b/activesupport/lib/active_support/core_ext/hash/except.rb
@@ -13,7 +13,7 @@ module ActiveSupport #:nodoc:
clone.except!(*keys)
end
- # Replaces the hash without only the given keys.
+ # Replaces the hash without the given keys.
def except!(*keys)
keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
keys.each { |key| delete(key) }
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 7af10846e7..546e261cc9 100644
--- a/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb
+++ b/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb
@@ -1,21 +1,28 @@
module ActiveSupport #:nodoc:
module CoreExtensions #:nodoc:
module Hash #:nodoc:
- # Allows for reverse merging where its the keys in the calling hash that wins over those in the <tt>other_hash</tt>.
- # This is particularly useful for initializing an incoming option hash with default values:
+ # Allows for reverse merging two hashes where the keys in the calling hash take precedence over those
+ # in the <tt>other_hash</tt>. This is particularly useful for initializing an option hash with default values:
#
# def setup(options = {})
# options.reverse_merge! :size => 25, :velocity => 10
# end
#
- # The default <tt>:size</tt> and <tt>:velocity</tt> is only set if the +options+ passed in doesn't already have those keys set.
+ # Using <tt>merge</tt>, the above example would look as follows:
+ #
+ # def setup(options = {})
+ # { :size => 25, :velocity => 10 }.merge(options)
+ # end
+ #
+ # The default <tt>:size</tt> and <tt>:velocity</tt> are only set if the +options+ hash passed in doesn't already
+ # have the respective key.
module ReverseMerge
- # Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
+ # Performs the opposite of <tt>merge</tt>, with the keys and values from the first hash taking precedence over the second.
def reverse_merge(other_hash)
other_hash.merge(self)
end
- # Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
+ # Performs the opposite of <tt>merge</tt>, with the keys and values from the first hash taking precedence over the second.
# Modifies the receiver in place.
def reverse_merge!(other_hash)
replace(reverse_merge(other_hash))
diff --git a/activesupport/lib/active_support/core_ext/hash/slice.rb b/activesupport/lib/active_support/core_ext/hash/slice.rb
index be4dec6e53..3f14470f36 100644
--- a/activesupport/lib/active_support/core_ext/hash/slice.rb
+++ b/activesupport/lib/active_support/core_ext/hash/slice.rb
@@ -9,6 +9,11 @@ module ActiveSupport #:nodoc:
# end
#
# search(options.slice(:mass, :velocity, :time))
+ #
+ # If you have an array of keys you want to limit to, you should splat them:
+ #
+ # valid_keys = [:mass, :velocity, :time]
+ # search(options.slice(*valid_keys))
module Slice
# Returns a new hash with only the given keys.
def slice(*keys)
diff --git a/activesupport/lib/active_support/core_ext/kernel/debugger.rb b/activesupport/lib/active_support/core_ext/kernel/debugger.rb
index c74d6cf884..4007a647be 100644
--- a/activesupport/lib/active_support/core_ext/kernel/debugger.rb
+++ b/activesupport/lib/active_support/core_ext/kernel/debugger.rb
@@ -2,12 +2,12 @@ module Kernel
unless respond_to?(:debugger)
# Starts a debugging session if ruby-debug has been loaded (call script/server --debugger to do load it).
def debugger
- RAILS_DEFAULT_LOGGER.info "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n"
+ Rails.logger.info "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n"
end
end
-
+
def breakpoint
- RAILS_DEFAULT_LOGGER.info "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
+ Rails.logger.info "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
debugger
end
-end \ No newline at end of file
+end
diff --git a/activesupport/lib/active_support/core_ext/object.rb b/activesupport/lib/active_support/core_ext/object.rb
index bbc7d81672..0796a7b710 100644
--- a/activesupport/lib/active_support/core_ext/object.rb
+++ b/activesupport/lib/active_support/core_ext/object.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/object/conversions'
require 'active_support/core_ext/object/extending'
require 'active_support/core_ext/object/instance_variables'
+require 'active_support/core_ext/object/metaclass'
require 'active_support/core_ext/object/misc'
diff --git a/activesupport/lib/active_support/core_ext/object/metaclass.rb b/activesupport/lib/active_support/core_ext/object/metaclass.rb
new file mode 100644
index 0000000000..93fb0ad594
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/object/metaclass.rb
@@ -0,0 +1,13 @@
+class Object
+ # Get object's meta (ghost, eigenclass, singleton) class
+ def metaclass
+ class << self
+ self
+ end
+ end
+
+ # If class_eval is called on an object, add those methods to its metaclass
+ def class_eval(*args, &block)
+ metaclass.class_eval(*args, &block)
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb
index a009d7c085..3bbad7dad8 100644
--- a/activesupport/lib/active_support/core_ext/string/inflections.rb
+++ b/activesupport/lib/active_support/core_ext/string/inflections.rb
@@ -24,8 +24,8 @@ module ActiveSupport #:nodoc:
#
# "posts".singularize # => "post"
# "octopi".singularize # => "octopus"
- # "sheep".singluarize # => "sheep"
- # "word".singluarize # => "word"
+ # "sheep".singularize # => "sheep"
+ # "word".singularize # => "word"
# "the blue mailmen".singularize # => "the blue mailman"
# "CamelOctopi".singularize # => "CamelOctopus"
def singularize
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index 2cce782676..cd234c9b89 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -261,7 +261,7 @@ module ActiveSupport #:nodoc:
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
# can be chronologically compared with a Time
def compare_with_coercion(other)
- # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do <=> comparision
+ # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do <=> comparison
other = other.comparable_time if other.respond_to?(:comparable_time)
if other.acts_like?(:date)
# other is a Date/DateTime, so coerce self #to_datetime and hand off to DateTime#<=>
diff --git a/activesupport/lib/active_support/core_ext/time/conversions.rb b/activesupport/lib/active_support/core_ext/time/conversions.rb
index 9054008309..f42be46770 100644
--- a/activesupport/lib/active_support/core_ext/time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/time/conversions.rb
@@ -30,6 +30,7 @@ module ActiveSupport #:nodoc:
# time.to_s(:time) # => "06:10:17"
#
# time.to_formatted_s(:db) # => "2007-01-18 06:10:17"
+ # time.to_formatted_s(:number) # => "20070118061017"
# time.to_formatted_s(:short) # => "18 Jan 06:10"
# time.to_formatted_s(:long) # => "January 18, 2007 06:10"
# time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"