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/backtrace_cleaner.rb44
-rw-r--r--activesupport/lib/active_support/benchmarkable.rb33
-rw-r--r--activesupport/lib/active_support/cache.rb150
-rw-r--r--activesupport/lib/active_support/callbacks.rb156
-rw-r--r--activesupport/lib/active_support/concern.rb21
-rw-r--r--activesupport/lib/active_support/configurable.rb26
-rw-r--r--activesupport/lib/active_support/core_ext/array/conversions.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/array/extract_options.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/array/grouping.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/array/uniq_by.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/array/wrap.rb23
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/date/calculations.rb211
-rw-r--r--activesupport/lib/active_support/core_ext/date/conversions.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/date/zones.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/date_and_time/calculations.rb232
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/calculations.rb52
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/conversions.rb7
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/zones.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/enumerable.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/file/atomic.rb32
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/hash/deep_merge.rb18
-rw-r--r--activesupport/lib/active_support/core_ext/hash/except.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/hash/indifferent_access.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/hash/keys.rb14
-rw-r--r--activesupport/lib/active_support/core_ext/hash/reverse_merge.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/hash/slice.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/integer/inflections.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/integer/time.rb20
-rw-r--r--activesupport/lib/active_support/core_ext/kernel/reporting.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/module/anonymous.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb36
-rw-r--r--activesupport/lib/active_support/core_ext/module/deprecation.rb16
-rw-r--r--activesupport/lib/active_support/core_ext/module/introspection.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/numeric/conversions.rb128
-rw-r--r--activesupport/lib/active_support/core_ext/numeric/time.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/object/blank.rb9
-rw-r--r--activesupport/lib/active_support/core_ext/object/duplicable.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/object/to_json.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/object/with_options.rb15
-rw-r--r--activesupport/lib/active_support/core_ext/string/filters.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb220
-rw-r--r--activesupport/lib/active_support/core_ext/time/conversions.rb24
-rw-r--r--activesupport/lib/active_support/core_ext/time/zones.rb6
-rw-r--r--activesupport/lib/active_support/dependencies.rb166
-rw-r--r--activesupport/lib/active_support/dependencies/autoload.rb59
-rw-r--r--activesupport/lib/active_support/deprecation.rb35
-rw-r--r--activesupport/lib/active_support/deprecation/behaviors.rb68
-rw-r--r--activesupport/lib/active_support/deprecation/instance_delegator.rb24
-rw-r--r--activesupport/lib/active_support/deprecation/method_wrappers.rb70
-rw-r--r--activesupport/lib/active_support/deprecation/proxy_wrappers.rb71
-rw-r--r--activesupport/lib/active_support/deprecation/reporting.rb39
-rw-r--r--activesupport/lib/active_support/duration.rb6
-rw-r--r--activesupport/lib/active_support/file_update_checker.rb18
-rw-r--r--activesupport/lib/active_support/hash_with_indifferent_access.rb65
-rw-r--r--activesupport/lib/active_support/i18n_railtie.rb4
-rw-r--r--activesupport/lib/active_support/inflector/inflections.rb112
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb186
-rw-r--r--activesupport/lib/active_support/inflector/transliterate.rb31
-rw-r--r--activesupport/lib/active_support/json/decoding.rb6
-rw-r--r--activesupport/lib/active_support/json/encoding.rb26
-rw-r--r--activesupport/lib/active_support/lazy_load_hooks.rb18
-rw-r--r--activesupport/lib/active_support/log_subscriber.rb24
-rw-r--r--activesupport/lib/active_support/log_subscriber/test_helper.rb19
-rw-r--r--activesupport/lib/active_support/logger.rb2
-rw-r--r--activesupport/lib/active_support/message_encryptor.rb42
-rw-r--r--activesupport/lib/active_support/message_verifier.rb14
-rw-r--r--activesupport/lib/active_support/multibyte.rb9
-rw-r--r--activesupport/lib/active_support/multibyte/chars.rb60
-rw-r--r--activesupport/lib/active_support/multibyte/unicode.rb52
-rw-r--r--activesupport/lib/active_support/notifications.rb19
-rw-r--r--activesupport/lib/active_support/notifications/instrumenter.rb2
-rw-r--r--activesupport/lib/active_support/number_helper.rb20
-rw-r--r--activesupport/lib/active_support/ordered_options.rb33
-rw-r--r--activesupport/lib/active_support/queueing.rb133
-rw-r--r--activesupport/lib/active_support/railtie.rb13
-rw-r--r--activesupport/lib/active_support/rescuable.rb6
-rw-r--r--activesupport/lib/active_support/string_inquirer.rb3
-rw-r--r--activesupport/lib/active_support/tagged_logging.rb59
-rw-r--r--activesupport/lib/active_support/test_case.rb3
-rw-r--r--activesupport/lib/active_support/testing/assertions.rb8
-rw-r--r--activesupport/lib/active_support/testing/constant_lookup.rb52
-rw-r--r--activesupport/lib/active_support/testing/performance.rb8
-rw-r--r--activesupport/lib/active_support/testing/tagged_logging.rb30
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb46
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb87
-rw-r--r--activesupport/lib/active_support/xml_mini/libxml.rb2
-rw-r--r--activesupport/lib/active_support/xml_mini/nokogiri.rb2
-rw-r--r--activesupport/lib/active_support/xml_mini/rexml.rb2
91 files changed, 1907 insertions, 1466 deletions
diff --git a/activesupport/lib/active_support/backtrace_cleaner.rb b/activesupport/lib/active_support/backtrace_cleaner.rb
index 7c3a41288b..53d05c3817 100644
--- a/activesupport/lib/active_support/backtrace_cleaner.rb
+++ b/activesupport/lib/active_support/backtrace_cleaner.rb
@@ -1,22 +1,29 @@
module ActiveSupport
- # Backtraces often include many lines that are not relevant for the context under review. This makes it hard to find the
- # signal amongst the backtrace noise, and adds debugging time. With a BacktraceCleaner, filters and silencers are used to
- # remove the noisy lines, so that only the most relevant lines remain.
+ # Backtraces often include many lines that are not relevant for the context
+ # under review. This makes it hard to find the signal amongst the backtrace
+ # noise, and adds debugging time. With a BacktraceCleaner, filters and
+ # silencers are used to remove the noisy lines, so that only the most relevant
+ # lines remain.
#
- # Filters are used to modify lines of data, while silencers are used to remove lines entirely. The typical filter use case
- # is to remove lengthy path information from the start of each line, and view file paths relevant to the app directory
- # instead of the file system root. The typical silencer use case is to exclude the output of a noisy library from the
- # backtrace, so that you can focus on the rest.
+ # Filters are used to modify lines of data, while silencers are used to remove
+ # lines entirely. The typical filter use case is to remove lengthy path
+ # information from the start of each line, and view file paths relevant to the
+ # app directory instead of the file system root. The typical silencer use case
+ # is to exclude the output of a noisy library from the backtrace, so that you
+ # can focus on the rest.
#
# bc = BacktraceCleaner.new
# bc.add_filter { |line| line.gsub(Rails.root, '') }
# bc.add_silencer { |line| line =~ /mongrel|rubygems/ }
# bc.clean(exception.backtrace) # will strip the Rails.root prefix and skip any lines from mongrel or rubygems
#
- # To reconfigure an existing BacktraceCleaner (like the default one in Rails) and show as much data as possible, you can
- # always call <tt>BacktraceCleaner#remove_silencers!</tt>, which will restore the backtrace to a pristine state. If you
- # need to reconfigure an existing BacktraceCleaner so that it does not filter or modify the paths of any lines of the
- # backtrace, you can call BacktraceCleaner#remove_filters! These two methods will give you a completely untouched backtrace.
+ # To reconfigure an existing BacktraceCleaner (like the default one in Rails)
+ # and show as much data as possible, you can always call
+ # <tt>BacktraceCleaner#remove_silencers!</tt>, which will restore the
+ # backtrace to a pristine state. If you need to reconfigure an existing
+ # BacktraceCleaner so that it does not filter or modify the paths of any lines
+ # of the backtrace, you can call BacktraceCleaner#remove_filters! These two
+ # methods will give you a completely untouched backtrace.
#
# Inspired by the Quiet Backtrace gem by Thoughtbot.
class BacktraceCleaner
@@ -24,7 +31,8 @@ module ActiveSupport
@filters, @silencers = [], []
end
- # Returns the backtrace after all filters and silencers have been run against it. Filters run first, then silencers.
+ # Returns the backtrace after all filters and silencers have been run
+ # against it. Filters run first, then silencers.
def clean(backtrace, kind = :silent)
filtered = filter(backtrace)
@@ -38,7 +46,8 @@ module ActiveSupport
end
end
- # Adds a filter from the block provided. Each line in the backtrace will be mapped against this filter.
+ # Adds a filter from the block provided. Each line in the backtrace will be
+ # mapped against this filter.
#
# # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
# backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') }
@@ -46,8 +55,8 @@ module ActiveSupport
@filters << block
end
- # Adds a silencer from the block provided. If the silencer returns true for a given line, it will be excluded from
- # the clean backtrace.
+ # Adds a silencer from the block provided. If the silencer returns +true+
+ # for a given line, it will be excluded from the clean backtrace.
#
# # Will reject all lines that include the word "mongrel", like "/gems/mongrel/server.rb" or "/app/my_mongrel_server/rb"
# backtrace_cleaner.add_silencer { |line| line =~ /mongrel/ }
@@ -55,8 +64,9 @@ module ActiveSupport
@silencers << block
end
- # Will remove all silencers, but leave in the filters. This is useful if your context of debugging suddenly expands as
- # you suspect a bug in one of the libraries you use.
+ # Will remove all silencers, but leave in the filters. This is useful if
+ # your context of debugging suddenly expands as you suspect a bug in one of
+ # the libraries you use.
def remove_silencers!
@silencers = []
end
diff --git a/activesupport/lib/active_support/benchmarkable.rb b/activesupport/lib/active_support/benchmarkable.rb
index f149a7f0ed..3d8bb13c49 100644
--- a/activesupport/lib/active_support/benchmarkable.rb
+++ b/activesupport/lib/active_support/benchmarkable.rb
@@ -3,30 +3,33 @@ require 'active_support/core_ext/hash/keys'
module ActiveSupport
module Benchmarkable
- # Allows you to measure the execution time of a block in a template and records the result to
- # the log. Wrap this block around expensive operations or possible bottlenecks to get a time
- # reading for the operation. For example, let's say you thought your file processing method
- # was taking too long; you could wrap it in a benchmark block.
+ # Allows you to measure the execution time of a block in a template and
+ # records the result to the log. Wrap this block around expensive operations
+ # or possible bottlenecks to get a time reading for the operation. For
+ # example, let's say you thought your file processing method was taking too
+ # long; you could wrap it in a benchmark block.
#
- # <% benchmark "Process data files" do %>
+ # <% benchmark 'Process data files' do %>
# <%= expensive_files_operation %>
# <% end %>
#
- # That would add something like "Process data files (345.2ms)" to the log, which you can then
- # use to compare timings when optimizing your code.
+ # That would add something like "Process data files (345.2ms)" to the log,
+ # which you can then use to compare timings when optimizing your code.
#
- # You may give an optional logger level (:debug, :info, :warn, :error) as the :level option.
- # The default logger level value is :info.
+ # You may give an optional logger level (<tt>:debug</tt>, <tt>:info</tt>,
+ # <tt>:warn</tt>, <tt>:error</tt>) as the <tt>:level</tt> option. The
+ # default logger level value is <tt>:info</tt>.
#
- # <% benchmark "Low-level files", :level => :debug do %>
+ # <% benchmark 'Low-level files', level: :debug do %>
# <%= lowlevel_files_operation %>
# <% end %>
#
- # Finally, you can pass true as the third argument to silence all log activity (other than the
- # timing information) from inside the block. This is great for boiling down a noisy block to
- # just a single statement that produces one log line:
+ # Finally, you can pass true as the third argument to silence all log
+ # activity (other than the timing information) from inside the block. This
+ # is great for boiling down a noisy block to just a single statement that
+ # produces one log line:
#
- # <% benchmark "Process data files", :level => :info, :silence => true do %>
+ # <% benchmark 'Process data files', level: :info, silence: true do %>
# <%= expensive_and_chatty_files_operation %>
# <% end %>
def benchmark(message = "Benchmarking", options = {})
@@ -44,8 +47,8 @@ module ActiveSupport
end
# Silence the logger during the execution of the block.
- #
def silence
+ ActiveSupport::Deprecation.warn "ActiveSupport::Benchmarkable#silence is deprecated. It will be removed from Rails 4.1."
old_logger_level, logger.level = logger.level, ::Logger::ERROR if logger
yield
ensure
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index a62214d604..f98ba16cdd 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -45,8 +45,8 @@ module ActiveSupport
# Any additional arguments will be passed to the corresponding cache store
# class's constructor:
#
- # ActiveSupport::Cache.lookup_store(:file_store, "/tmp/cache")
- # # => same as: ActiveSupport::Cache::FileStore.new("/tmp/cache")
+ # ActiveSupport::Cache.lookup_store(:file_store, '/tmp/cache')
+ # # => same as: ActiveSupport::Cache::FileStore.new('/tmp/cache')
#
# If the first argument is not a Symbol, then it will simply be returned:
#
@@ -110,9 +110,9 @@ module ActiveSupport
#
# cache = ActiveSupport::Cache::MemoryStore.new
#
- # cache.read("city") # => nil
- # cache.write("city", "Duckburgh")
- # cache.read("city") # => "Duckburgh"
+ # cache.read('city') # => nil
+ # cache.write('city', "Duckburgh")
+ # cache.read('city') # => "Duckburgh"
#
# Keys are always translated into Strings and are case sensitive. When an
# object is specified as a key and has a +cache_key+ method defined, this
@@ -121,7 +121,7 @@ module ActiveSupport
# elements will be delimited by slashes, and the elements within a Hash
# will be sorted by key so they are consistent.
#
- # cache.read("city") == cache.read(:city) # => true
+ # cache.read('city') == cache.read(:city) # => true
#
# Nil values can be cached.
#
@@ -131,14 +131,13 @@ module ActiveSupport
# is a Proc, it will be invoked when each key is evaluated so that you can
# use application logic to invalidate keys.
#
- # cache.namespace = lambda { @last_mod_time } # Set the namespace to a variable
+ # cache.namespace = -> { @last_mod_time } # Set the namespace to a variable
# @last_mod_time = Time.now # Invalidate the entire cache by changing namespace
#
- #
# Caches can also store values in a compressed format to save space and
# reduce time spent sending data. Since there is overhead, values must be
# large enough to warrant compression. To turn on compression either pass
- # <tt>:compress => true</tt> in the initializer or as an option to +fetch+
+ # <tt>compress: true</tt> in the initializer or as an option to +fetch+
# or +write+. To specify the threshold at which to compress values, set the
# <tt>:compress_threshold</tt> option. The default threshold is 16K.
class Store
@@ -148,8 +147,9 @@ module ActiveSupport
attr_reader :silence, :options
alias :silence? :silence
- # Create a new cache. The options will be passed to any write method calls except
- # for :namespace which can be used to set the global namespace for the cache.
+ # Create a new cache. The options will be passed to any write method calls
+ # except for <tt>:namespace</tt> which can be used to set the global
+ # namespace for the cache.
def initialize(options = nil)
@options = options ? options.dup : {}
end
@@ -168,7 +168,8 @@ module ActiveSupport
@silence = previous_silence
end
- # Set to true if cache stores should be instrumented. Default is false.
+ # Set to +true+ if cache stores should be instrumented.
+ # Default is +false+.
def self.instrument=(boolean)
Thread.current[:instrument_cache_store] = boolean
end
@@ -180,95 +181,97 @@ module ActiveSupport
# Fetches data from the cache, using the given key. If there is data in
# the cache with the given key, then that data is returned.
#
- # If there is no such data in the cache (a cache miss), then nil will be
+ # If there is no such data in the cache (a cache miss), then +nil+ will be
# returned. However, if a block has been passed, that block will be run
# in the event of a cache miss. The return value of the block will be
# written to the cache under the given cache key, and that return value
# will be returned.
#
- # cache.write("today", "Monday")
- # cache.fetch("today") # => "Monday"
+ # cache.write('today', 'Monday')
+ # cache.fetch('today') # => "Monday"
#
- # cache.fetch("city") # => nil
- # cache.fetch("city") do
- # "Duckburgh"
+ # cache.fetch('city') # => nil
+ # cache.fetch('city') do
+ # 'Duckburgh'
# end
- # cache.fetch("city") # => "Duckburgh"
+ # cache.fetch('city') # => "Duckburgh"
#
# You may also specify additional options via the +options+ argument.
- # Setting <tt>:force => true</tt> will force a cache miss:
+ # Setting <tt>force: true</tt> will force a cache miss:
#
- # cache.write("today", "Monday")
- # cache.fetch("today", :force => true) # => nil
+ # cache.write('today', 'Monday')
+ # cache.fetch('today', force: true) # => nil
#
# Setting <tt>:compress</tt> will store a large cache entry set by the call
# in a compressed format.
#
- #
# Setting <tt>:expires_in</tt> will set an expiration time on the cache.
# All caches support auto-expiring content after a specified number of
# seconds. This value can be specified as an option to the constructor
# (in which case all entries will be affected), or it can be supplied to
# the +fetch+ or +write+ method to effect just one entry.
#
- # cache = ActiveSupport::Cache::MemoryStore.new(:expires_in => 5.minutes)
- # cache.write(key, value, :expires_in => 1.minute) # Set a lower value for one entry
- #
- # Setting <tt>:race_condition_ttl</tt> is very useful in situations where a cache entry
- # is used very frequently and is under heavy load. If a cache expires and due to heavy load
- # seven different processes will try to read data natively and then they all will try to
- # write to cache. To avoid that case the first process to find an expired cache entry will
- # bump the cache expiration time by the value set in <tt>:race_condition_ttl</tt>. Yes
- # this process is extending the time for a stale value by another few seconds. Because
- # of extended life of the previous cache, other processes will continue to use slightly
- # stale data for a just a big longer. In the meantime that first process will go ahead
- # and will write into cache the new value. After that all the processes will start
- # getting new value. The key is to keep <tt>:race_condition_ttl</tt> small.
- #
- # If the process regenerating the entry errors out, the entry will be regenerated
- # after the specified number of seconds. Also note that the life of stale cache is
- # extended only if it expired recently. Otherwise a new value is generated and
- # <tt>:race_condition_ttl</tt> does not play any role.
+ # cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
+ # cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry
+ #
+ # Setting <tt>:race_condition_ttl</tt> is very useful in situations where
+ # a cache entry is used very frequently and is under heavy load. If a
+ # cache expires and due to heavy load seven different processes will try
+ # to read data natively and then they all will try to write to cache. To
+ # avoid that case the first process to find an expired cache entry will
+ # bump the cache expiration time by the value set in <tt>:race_condition_ttl</tt>.
+ # Yes, this process is extending the time for a stale value by another few
+ # seconds. Because of extended life of the previous cache, other processes
+ # will continue to use slightly stale data for a just a big longer. In the
+ # meantime that first process will go ahead and will write into cache the
+ # new value. After that all the processes will start getting new value.
+ # The key is to keep <tt>:race_condition_ttl</tt> small.
+ #
+ # If the process regenerating the entry errors out, the entry will be
+ # regenerated after the specified number of seconds. Also note that the
+ # life of stale cache is extended only if it expired recently. Otherwise
+ # a new value is generated and <tt>:race_condition_ttl</tt> does not play
+ # any role.
#
# # Set all values to expire after one minute.
- # cache = ActiveSupport::Cache::MemoryStore.new(:expires_in => 1.minute)
+ # cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1.minute)
#
- # cache.write("foo", "original value")
+ # cache.write('foo', 'original value')
# val_1 = nil
# val_2 = nil
# sleep 60
#
# Thread.new do
- # val_1 = cache.fetch("foo", :race_condition_ttl => 10) do
+ # val_1 = cache.fetch('foo', race_condition_ttl: 10) do
# sleep 1
- # "new value 1"
+ # 'new value 1'
# end
# end
#
# Thread.new do
- # val_2 = cache.fetch("foo", :race_condition_ttl => 10) do
- # "new value 2"
+ # val_2 = cache.fetch('foo', race_condition_ttl: 10) do
+ # 'new value 2'
# end
# end
#
# # val_1 => "new value 1"
# # val_2 => "original value"
# # sleep 10 # First thread extend the life of cache by another 10 seconds
- # # cache.fetch("foo") => "new value 1"
+ # # cache.fetch('foo') => "new value 1"
#
# Other options will be handled by the specific cache store implementation.
- # Internally, #fetch calls #read_entry, and calls #write_entry on a cache miss.
- # +options+ will be passed to the #read and #write calls.
+ # Internally, #fetch calls #read_entry, and calls #write_entry on a cache
+ # miss. +options+ will be passed to the #read and #write calls.
#
# For example, MemCacheStore's #write method supports the +:raw+
# option, which tells the memcached server to store all values as strings.
# We can use this option with #fetch too:
#
# cache = ActiveSupport::Cache::MemCacheStore.new
- # cache.fetch("foo", :force => true, :raw => true) do
+ # cache.fetch("foo", force: true, raw: true) do
# :bar
# end
- # cache.fetch("foo") # => "bar"
+ # cache.fetch('foo') # => "bar"
def fetch(name, options = nil)
if block_given?
options = merged_options(options)
@@ -307,7 +310,7 @@ module ActiveSupport
# Fetches data from the cache, using the given key. If there is data in
# the cache with the given key, then that data is returned. Otherwise,
- # nil is returned.
+ # +nil+ is returned.
#
# Options are passed to the underlying cache implementation.
def read(name, options = nil)
@@ -376,7 +379,7 @@ module ActiveSupport
end
end
- # Return true if the cache contains an entry for the given key.
+ # Return +true+ if the cache contains an entry for the given key.
#
# Options are passed to the underlying cache implementation.
def exist?(name, options = nil)
@@ -434,9 +437,10 @@ module ActiveSupport
end
protected
- # Add the namespace defined in the options to a pattern designed to match keys.
- # Implementations that support delete_matched should call this method to translate
- # a pattern that matches names into one that matches namespaced keys.
+ # Add the namespace defined in the options to a pattern designed to
+ # match keys. Implementations that support delete_matched should call
+ # this method to translate a pattern that matches names into one that
+ # matches namespaced keys.
def key_matcher(pattern, options)
prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace]
if prefix
@@ -452,17 +456,20 @@ module ActiveSupport
end
end
- # Read an entry from the cache implementation. Subclasses must implement this method.
+ # Read an entry from the cache implementation. Subclasses must implement
+ # this method.
def read_entry(key, options) # :nodoc:
raise NotImplementedError.new
end
- # Write an entry to the cache implementation. Subclasses must implement this method.
+ # Write an entry to the cache implementation. Subclasses must implement
+ # this method.
def write_entry(key, entry, options) # :nodoc:
raise NotImplementedError.new
end
- # Delete an entry from the cache implementation. Subclasses must implement this method.
+ # Delete an entry from the cache implementation. Subclasses must
+ # implement this method.
def delete_entry(key, options) # :nodoc:
raise NotImplementedError.new
end
@@ -478,7 +485,7 @@ module ActiveSupport
end
# Expand key to be a consistent string value. Invoke +cache_key+ if
- # object responds to +cache_key+. Otherwise, to_param method will be
+ # object responds to +cache_key+. Otherwise, +to_param+ method will be
# called. If the key is a Hash, then keys will be sorted alphabetically.
def expanded_key(key) # :nodoc:
return key.cache_key.to_s if key.respond_to?(:cache_key)
@@ -497,7 +504,8 @@ module ActiveSupport
key.to_param
end
- # Prefix a key with the namespace. Namespace and key will be delimited with a colon.
+ # Prefix a key with the namespace. Namespace and key will be delimited
+ # with a colon.
def namespaced_key(key, options)
key = expanded_key(key)
namespace = options[:namespace] if options
@@ -524,17 +532,17 @@ module ActiveSupport
end
end
- # Entry that is put into caches. It supports expiration time on entries and can compress values
- # to save space in the cache.
+ # Entry that is put into caches. It supports expiration time on entries and
+ # can compress values to save space in the cache.
class Entry
attr_reader :created_at, :expires_in
DEFAULT_COMPRESS_LIMIT = 16.kilobytes
class << self
- # Create an entry with internal attributes set. This method is intended to be
- # used by implementations that store cache entries in a native format instead
- # of as serialized Ruby objects.
+ # Create an entry with internal attributes set. This method is intended
+ # to be used by implementations that store cache entries in a native
+ # format instead of as serialized Ruby objects.
def create(raw_value, created_at, options = {})
entry = new(nil)
entry.instance_variable_set(:@value, raw_value)
@@ -582,8 +590,8 @@ module ActiveSupport
@compressed
end
- # Check if the entry is expired. The +expires_in+ parameter can override the
- # value set when the entry was created.
+ # Check if the entry is expired. The +expires_in+ parameter can override
+ # the value set when the entry was created.
def expired?
@expires_in && @created_at + @expires_in <= Time.now.to_f
end
@@ -602,8 +610,8 @@ module ActiveSupport
@expires_in ? @created_at + @expires_in : nil
end
- # Returns the size of the cached value. This could be less than value.size
- # if the data is compressed.
+ # Returns the size of the cached value. This could be less than
+ # <tt>value.size</tt> if the data is compressed.
def size
if @value.nil?
0
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 3f7d0e401a..a02793bde9 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -5,22 +5,24 @@ require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/kernel/singleton_class'
module ActiveSupport
- # \Callbacks are code hooks that are run at key points in an object's lifecycle.
- # The typical use case is to have a base class define a set of callbacks relevant
- # to the other functionality it supplies, so that subclasses can install callbacks
- # that enhance or modify the base functionality without needing to override
- # or redefine methods of the base class.
+ # Callbacks are code hooks that are run at key points in an object's lifecycle.
+ # The typical use case is to have a base class define a set of callbacks
+ # relevant to the other functionality it supplies, so that subclasses can
+ # install callbacks that enhance or modify the base functionality without
+ # needing to override or redefine methods of the base class.
#
- # Mixing in this module allows you to define the events in the object's lifecycle
- # that will support callbacks (via +ClassMethods.define_callbacks+), set the instance
- # methods, procs, or callback objects to be called (via +ClassMethods.set_callback+),
- # and run the installed callbacks at the appropriate times (via +run_callbacks+).
+ # Mixing in this module allows you to define the events in the object's
+ # lifecycle that will support callbacks (via +ClassMethods.define_callbacks+),
+ # set the instance methods, procs, or callback objects to be called (via
+ # +ClassMethods.set_callback+), and run the installed callbacks at the
+ # appropriate times (via +run_callbacks+).
#
- # Three kinds of callbacks are supported: before callbacks, run before a certain event;
- # after callbacks, run after the event; and around callbacks, blocks that surround the
- # event, triggering it when they yield. Callback code can be contained in instance
- # methods, procs or lambdas, or callback objects that respond to certain predetermined
- # methods. See +ClassMethods.set_callback+ for details.
+ # Three kinds of callbacks are supported: before callbacks, run before a
+ # certain event; after callbacks, run after the event; and around callbacks,
+ # blocks that surround the event, triggering it when they yield. Callback code
+ # can be contained in instance methods, procs or lambdas, or callback objects
+ # that respond to certain predetermined methods. See +ClassMethods.set_callback+
+ # for details.
#
# class Record
# include ActiveSupport::Callbacks
@@ -61,10 +63,11 @@ module ActiveSupport
# Runs the callbacks for the given event.
#
# Calls the before and around callbacks in the order they were set, yields
- # the block (if given one), and then runs the after callbacks in reverse order.
+ # the block (if given one), and then runs the after callbacks in reverse
+ # order.
#
- # If the callback chain was halted, returns +false+. Otherwise returns the result
- # of the block, or +true+ if no block is given.
+ # If the callback chain was halted, returns +false+. Otherwise returns the
+ # result of the block, or +true+ if no block is given.
#
# run_callbacks :save do
# save
@@ -182,17 +185,17 @@ module ActiveSupport
# Compile around filters with conditions into proxy methods
# that contain the conditions.
#
- # For `set_callback :save, :around, :filter_name, :if => :condition':
+ # For `set_callback :save, :around, :filter_name, if: :condition':
#
- # def _conditional_callback_save_17
- # if condition
- # filter_name do
+ # def _conditional_callback_save_17
+ # if condition
+ # filter_name do
+ # yield self
+ # end
+ # else
# yield self
# end
- # else
- # yield self
# end
- # end
def define_conditional_callback
name = "_conditional_callback_#{@kind}_#{next_id}"
@klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
@@ -211,7 +214,7 @@ module ActiveSupport
# Options support the same options as filters themselves (and support
# symbols, string, procs, and objects), so compile a conditional
- # expression based on the options
+ # expression based on the options.
def recompile_options!
conditions = ["true"]
@@ -230,19 +233,19 @@ module ActiveSupport
#
# Arrays:: Used in conditions. This is used to specify
# multiple conditions. Used internally to
- # merge conditions from skip_* filters
- # Symbols:: A method to call
- # Strings:: Some content to evaluate
- # Procs:: A proc to call with the object
- # Objects:: An object with a before_foo method on it to call
+ # merge conditions from skip_* filters.
+ # Symbols:: A method to call.
+ # Strings:: Some content to evaluate.
+ # Procs:: A proc to call with the object.
+ # Objects:: An object with a <tt>before_foo</tt> method on it to call.
#
# All of these objects are compiled into methods and handled
# the same after this point:
#
- # Arrays:: Merged together into a single filter
- # Symbols:: Already methods
- # Strings:: class_eval'ed into methods
- # Procs:: define_method'ed into methods
+ # Arrays:: Merged together into a single filter.
+ # Symbols:: Already methods.
+ # Strings:: class_eval'ed into methods.
+ # Procs:: define_method'ed into methods.
# Objects::
# a method is created that calls the before_foo method
# on the object.
@@ -279,6 +282,7 @@ module ActiveSupport
def _normalize_legacy_filter(kind, filter)
if !filter.respond_to?(kind) && filter.respond_to?(:filter)
+ ActiveSupport::Deprecation.warn("Filter object with #filter method is deprecated. Define method corresponding to filter type (#before, #after or #around).")
filter.singleton_class.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def #{kind}(context, &block) filter(context, &block) end
RUBY_EVAL
@@ -293,7 +297,7 @@ module ActiveSupport
end
end
- # An Array with a compile method
+ # An Array with a compile method.
class CallbackChain < Array #:nodoc:#
attr_reader :name, :config
@@ -350,7 +354,6 @@ module ActiveSupport
# This is used internally to append, prepend and skip callbacks to the
# CallbackChain.
- #
def __update_callbacks(name, filters = [], block = nil) #:nodoc:
type = [:before, :after, :around].include?(filters.first) ? filters.shift : :before
options = filters.last.is_a?(Hash) ? filters.pop : {}
@@ -366,8 +369,8 @@ module ActiveSupport
# Install a callback for the given event.
#
# set_callback :save, :before, :before_meth
- # set_callback :save, :after, :after_meth, :if => :condition
- # set_callback :save, :around, lambda { |r| stuff; result = yield; stuff }
+ # set_callback :save, :after, :after_meth, if: :condition
+ # set_callback :save, :around, ->(r, &block) { stuff; result = block.call; stuff }
#
# The second arguments indicates whether the callback is to be run +:before+,
# +:after+, or +:around+ the event. If omitted, +:before+ is assumed. This
@@ -375,29 +378,29 @@ module ActiveSupport
#
# set_callback :save, :before_meth
#
- # The callback can specified as a symbol naming an instance method; as a proc,
- # lambda, or block; as a string to be instance evaluated; or as an object that
- # responds to a certain method determined by the <tt>:scope</tt> argument to
- # +define_callback+.
+ # The callback can specified as a symbol naming an instance method; as a
+ # proc, lambda, or block; as a string to be instance evaluated; or as an
+ # object that responds to a certain method determined by the <tt>:scope</tt>
+ # argument to +define_callback+.
#
# If a proc, lambda, or block is given, its body is evaluated in the context
# of the current object. It can also optionally accept the current object as
# an argument.
#
- # Before and around callbacks are called in the order that they are set; after
- # callbacks are called in the reverse order.
- #
+ # Before and around callbacks are called in the order that they are set;
+ # after callbacks are called in the reverse order.
+ #
# Around callbacks can access the return value from the event, if it
# wasn't halted, from the +yield+ call.
#
# ===== Options
#
- # * <tt>:if</tt> - A symbol naming an instance method or a proc; the callback
- # will be called only when it returns a true value.
- # * <tt>:unless</tt> - A symbol naming an instance method or a proc; the callback
- # will be called only when it returns a false value.
- # * <tt>:prepend</tt> - If true, the callback will be prepended to the existing
- # chain rather than appended.
+ # * <tt>:if</tt> - A symbol naming an instance method or a proc; the
+ # callback will be called only when it returns a +true+ value.
+ # * <tt>:unless</tt> - A symbol naming an instance method or a proc; the
+ # callback will be called only when it returns a +false+ value.
+ # * <tt>:prepend</tt> - If +true+, the callback will be prepended to the
+ # existing chain rather than appended.
def set_callback(name, *filter_list, &block)
mapped = nil
@@ -416,11 +419,12 @@ module ActiveSupport
end
end
- # Skip a previously set callback. Like +set_callback+, <tt>:if</tt> or <tt>:unless</tt>
- # options may be passed in order to control when the callback is skipped.
+ # Skip a previously set callback. Like +set_callback+, <tt>:if</tt> or
+ # <tt>:unless</tt> options may be passed in order to control when the
+ # callback is skipped.
#
# class Writer < Person
- # skip_callback :validate, :before, :check_membership, :if => lambda { self.age > 18 }
+ # skip_callback :validate, :before, :check_membership, if: -> { self.age > 18 }
# end
def skip_callback(name, *filter_list, &block)
__update_callbacks(name, filter_list, block) do |target, chain, type, filters, options|
@@ -462,24 +466,25 @@ module ActiveSupport
#
# ===== Options
#
- # * <tt>:terminator</tt> - Determines when a before filter will halt the callback
- # chain, preventing following callbacks from being called and the event from being
- # triggered. This is a string to be eval'ed. The result of the callback is available
- # in the <tt>result</tt> variable.
+ # * <tt>:terminator</tt> - Determines when a before filter will halt the
+ # callback chain, preventing following callbacks from being called and
+ # the event from being triggered. This is a string to be eval'ed. The
+ # result of the callback is available in the +result+ variable.
#
- # define_callbacks :validate, :terminator => "result == false"
+ # define_callbacks :validate, terminator: 'result == false'
#
# In this example, if any before validate callbacks returns +false+,
- # other callbacks are not executed. Defaults to "false", meaning no value
+ # other callbacks are not executed. Defaults to +false+, meaning no value
# halts the chain.
#
- # * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after callbacks should be terminated
- # by the <tt>:terminator</tt> option. By default after callbacks executed no matter
- # if callback chain was terminated or not.
- # Option makes sence only when <tt>:terminator</tt> option is specified.
+ # * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after
+ # callbacks should be terminated by the <tt>:terminator</tt> option. By
+ # default after callbacks executed no matter if callback chain was
+ # terminated or not. Option makes sense only when <tt>:terminator</tt>
+ # option is specified.
#
- # * <tt>:scope</tt> - Indicates which methods should be executed when an object
- # is used as a callback.
+ # * <tt>:scope</tt> - Indicates which methods should be executed when an
+ # object is used as a callback.
#
# class Audit
# def before(caller)
@@ -504,20 +509,21 @@ module ActiveSupport
# end
# end
#
- # In the above case whenever you save an account the method <tt>Audit#before</tt> will
- # be called. On the other hand
+ # In the above case whenever you save an account the method
+ # <tt>Audit#before</tt> will be called. On the other hand
#
- # define_callbacks :save, :scope => [:kind, :name]
+ # define_callbacks :save, scope: [:kind, :name]
#
- # would trigger <tt>Audit#before_save</tt> instead. That's constructed by calling
- # <tt>#{kind}_#{name}</tt> on the given instance. In this case "kind" is "before" and
- # "name" is "save". In this context +:kind+ and +:name+ have special meanings: +:kind+
- # refers to the kind of callback (before/after/around) and +:name+ refers to the
- # method on which callbacks are being defined.
+ # would trigger <tt>Audit#before_save</tt> instead. That's constructed
+ # by calling <tt>#{kind}_#{name}</tt> on the given instance. In this
+ # case "kind" is "before" and "name" is "save". In this context +:kind+
+ # and +:name+ have special meanings: +:kind+ refers to the kind of
+ # callback (before/after/around) and +:name+ refers to the method on
+ # which callbacks are being defined.
#
# A declaration like
#
- # define_callbacks :save, :scope => [:name]
+ # define_callbacks :save, scope: [:name]
#
# would call <tt>Audit#save</tt>.
def define_callbacks(*callbacks)
diff --git a/activesupport/lib/active_support/concern.rb b/activesupport/lib/active_support/concern.rb
index b927b58a9a..fb7065ef3b 100644
--- a/activesupport/lib/active_support/concern.rb
+++ b/activesupport/lib/active_support/concern.rb
@@ -4,7 +4,7 @@ module ActiveSupport
# module M
# def self.included(base)
# base.extend ClassMethods
- # scope :disabled, where(:disabled => true)
+ # scope :disabled, -> { where(disabled: true) }
# end
#
# module ClassMethods
@@ -12,7 +12,8 @@ module ActiveSupport
# end
# end
#
- # By using <tt>ActiveSupport::Concern</tt> the above module could instead be written as:
+ # By using <tt>ActiveSupport::Concern</tt> the above module could instead be
+ # written as:
#
# require 'active_support/concern'
#
@@ -20,7 +21,7 @@ module ActiveSupport
# extend ActiveSupport::Concern
#
# included do
- # scope :disabled, where(:disabled => true)
+ # scope :disabled, -> { where(disabled: true) }
# end
#
# module ClassMethods
@@ -28,8 +29,9 @@ module ActiveSupport
# end
# end
#
- # Moreover, it gracefully handles module dependencies. Given a +Foo+ module and a +Bar+
- # module which depends on the former, we would typically write the following:
+ # Moreover, it gracefully handles module dependencies. Given a +Foo+ module
+ # and a +Bar+ module which depends on the former, we would typically write the
+ # following:
#
# module Foo
# def self.included(base)
@@ -52,8 +54,8 @@ module ActiveSupport
# include Bar # Bar is the module that Host really needs
# end
#
- # But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We could try to hide
- # these from +Host+ directly including +Foo+ in +Bar+:
+ # But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We
+ # could try to hide these from +Host+ directly including +Foo+ in +Bar+:
#
# module Bar
# include Foo
@@ -66,8 +68,9 @@ module ActiveSupport
# include Bar
# end
#
- # Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt> is the +Bar+ module,
- # not the +Host+ class. With <tt>ActiveSupport::Concern</tt>, module dependencies are properly resolved:
+ # Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt>
+ # is the +Bar+ module, not the +Host+ class. With <tt>ActiveSupport::Concern</tt>,
+ # module dependencies are properly resolved:
#
# require 'active_support/concern'
#
diff --git a/activesupport/lib/active_support/configurable.rb b/activesupport/lib/active_support/configurable.rb
index 307ae40398..16d2a6a290 100644
--- a/activesupport/lib/active_support/configurable.rb
+++ b/activesupport/lib/active_support/configurable.rb
@@ -13,7 +13,7 @@ module ActiveSupport
self.class.compile_methods!(keys)
end
- # compiles reader methods so we don't have to go through method_missing
+ # Compiles reader methods so we don't have to go through method_missing.
def self.compile_methods!(keys)
keys.reject { |m| method_defined?(m) }.each do |key|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
@@ -39,7 +39,7 @@ module ActiveSupport
# Allows you to add shortcut so that you don't have to refer to attribute
# through config. Also look at the example for config to contrast.
- #
+ #
# Defines both class and instance config accessors.
#
# class User
@@ -47,16 +47,16 @@ module ActiveSupport
# config_accessor :allowed_access
# end
#
- # User.allowed_access # => nil
+ # User.allowed_access # => nil
# User.allowed_access = false
- # User.allowed_access # => false
- #
+ # User.allowed_access # => false
+ #
# user = User.new
# user.allowed_access # => false
# user.allowed_access = true
# user.allowed_access # => true
#
- # User.allowed_access # => false
+ # User.allowed_access # => false
#
# The attribute name must be a valid method name in Ruby.
#
@@ -91,7 +91,18 @@ module ActiveSupport
#  User.allowed_access # => false
#
# User.new.allowed_access = true # => NoMethodError
- # User.new.allowed_access # => NoMethodError
+ # User.new.allowed_access # => NoMethodError
+ #
+ # Also you can pass a block to set up the attribute with a default value.
+ #
+ # class User
+ # include ActiveSupport::Configurable
+ # config_accessor :hair_colors do
+ # [:brown, :black, :blonde, :red]
+ # end
+ # end
+ #
+ # User.hair_colors # => [:brown, :black, :blonde, :red]
def config_accessor(*names)
options = names.extract_options!
@@ -108,6 +119,7 @@ module ActiveSupport
class_eval reader, __FILE__, reader_line unless options[:instance_reader] == false
class_eval writer, __FILE__, writer_line unless options[:instance_writer] == false
end
+ send("#{name}=", yield) if block_given?
end
end
end
diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb
index d6ae031c0d..7f37c459c1 100644
--- a/activesupport/lib/active_support/core_ext/array/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/array/conversions.rb
@@ -142,7 +142,7 @@ class Array
#
# Otherwise the root element is "objects":
#
- # [{:foo => 1, :bar => 2}, {:baz => 3}].to_xml
+ # [{ foo: 1, bar: 2}, { baz: 3}].to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <objects type="array">
@@ -164,7 +164,7 @@ class Array
#
# To ensure a meaningful root element use the <tt>:root</tt> option:
#
- # customer_with_no_projects.projects.to_xml(:root => "projects")
+ # customer_with_no_projects.projects.to_xml(root: 'projects')
#
# <?xml version="1.0" encoding="UTF-8"?>
# <projects type="array"/>
@@ -174,7 +174,7 @@ class Array
#
# The +options+ hash is passed downwards:
#
- # Message.all.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/array/extract_options.rb b/activesupport/lib/active_support/core_ext/array/extract_options.rb
index 40ceb3eb9e..9008a0df2a 100644
--- a/activesupport/lib/active_support/core_ext/array/extract_options.rb
+++ b/activesupport/lib/active_support/core_ext/array/extract_options.rb
@@ -17,8 +17,8 @@ class Array
# args.extract_options!
# end
#
- # options(1, 2) # => {}
- # options(1, 2, :a => :b) # => {:a=>:b}
+ # options(1, 2) # => {}
+ # options(1, 2, a: :b) # => {:a=>:b}
def extract_options!
if last.is_a?(Hash) && last.extractable_options?
pop
diff --git a/activesupport/lib/active_support/core_ext/array/grouping.rb b/activesupport/lib/active_support/core_ext/array/grouping.rb
index a184eb492a..f79b100b3b 100644
--- a/activesupport/lib/active_support/core_ext/array/grouping.rb
+++ b/activesupport/lib/active_support/core_ext/array/grouping.rb
@@ -83,8 +83,8 @@ class Array
# Divides the array into one or more subarrays based on a delimiting +value+
# or the result of an optional block.
#
- # [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]]
+ # [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)
inject([[]]) do |results, element|
if block && block.call(element) || value == element
diff --git a/activesupport/lib/active_support/core_ext/array/uniq_by.rb b/activesupport/lib/active_support/core_ext/array/uniq_by.rb
index 3bedfa9a61..c1d5a355a4 100644
--- a/activesupport/lib/active_support/core_ext/array/uniq_by.rb
+++ b/activesupport/lib/active_support/core_ext/array/uniq_by.rb
@@ -4,7 +4,6 @@ class Array
# Returns a unique array based on the criteria in the block.
#
# [1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2]
- #
def uniq_by(&block)
ActiveSupport::Deprecation.warn 'uniq_by is deprecated. Use Array#uniq instead', caller
uniq(&block)
diff --git a/activesupport/lib/active_support/core_ext/array/wrap.rb b/activesupport/lib/active_support/core_ext/array/wrap.rb
index 9ea93d7226..7bf28b2f27 100644
--- a/activesupport/lib/active_support/core_ext/array/wrap.rb
+++ b/activesupport/lib/active_support/core_ext/array/wrap.rb
@@ -7,32 +7,33 @@ class Array
# * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
# * Otherwise, returns an array with the argument as its single element.
#
- # Array.wrap(nil) # => []
- # Array.wrap([1, 2, 3]) # => [1, 2, 3]
- # Array.wrap(0) # => [0]
+ # Array.wrap(nil) # => []
+ # Array.wrap([1, 2, 3]) # => [1, 2, 3]
+ # Array.wrap(0) # => [0]
#
# This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
#
# * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
- # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
- # such a +nil+ right away.
+ # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
+ # such a +nil+ right away.
# * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
- # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
+ # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
# * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.
#
# The last point is particularly worth comparing for some enumerables:
#
- # Array(:foo => :bar) # => [[:foo, :bar]]
- # Array.wrap(:foo => :bar) # => [{:foo => :bar}]
+ # Array(foo: :bar) # => [[:foo, :bar]]
+ # Array.wrap(foo: :bar) # => [{:foo => :bar}]
#
# There's also a related idiom that uses the splat operator:
#
# [*object]
#
- # which returns <tt>[nil]</tt> for +nil+, and calls to <tt>Array(object)</tt> otherwise.
+ # which for +nil+ returns <tt>[nil]</tt> (Ruby 1.8.7) or <tt>[]</tt> (Ruby
+ # 1.9), and calls to <tt>Array(object)</tt> otherwise.
#
- # Thus, in this case the behavior is different for +nil+, and the differences with
- # <tt>Kernel#Array</tt> explained above apply to the rest of +object+s.
+ # Thus, in this case the behavior may be different for +nil+, and the differences with
+ # <tt>Kernel#Array</tt> explained above apply to the rest of <tt>object</tt>s.
def self.wrap(object)
if object.nil?
[]
diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb
index 7b6f8ab0a1..1c3d26ead4 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -57,16 +57,16 @@ class Class
# object.setting # => false
# Base.setting # => true
#
- # To opt out of the instance reader method, pass :instance_reader => false.
+ # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
#
# object.setting # => NoMethodError
# object.setting? # => NoMethodError
#
- # To opt out of the instance writer method, pass :instance_writer => false.
+ # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
#
# object.setting = false # => NoMethodError
#
- # To opt out of both instance methods, pass :instance_accessor => false.
+ # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
def class_attribute(*attrs)
options = attrs.extract_options!
instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb
index 7fe4161fb4..a7551d9c64 100644
--- a/activesupport/lib/active_support/core_ext/date/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date/calculations.rb
@@ -3,19 +3,35 @@ require 'active_support/duration'
require 'active_support/core_ext/object/acts_like'
require 'active_support/core_ext/date/zones'
require 'active_support/core_ext/time/zones'
+require 'active_support/core_ext/date_and_time/calculations'
class Date
- DAYS_INTO_WEEK = {
- :monday => 0,
- :tuesday => 1,
- :wednesday => 2,
- :thursday => 3,
- :friday => 4,
- :saturday => 5,
- :sunday => 6
- }
+ include DateAndTime::Calculations
class << self
+ attr_accessor :beginning_of_week_default
+
+ # Returns the week start (e.g. :monday) for the current request, if this has been set (via Date.beginning_of_week=).
+ # If <tt>Date.beginning_of_week</tt> has not been set for the current request, returns the week start specified in <tt>config.beginning_of_week</tt>.
+ # If no config.beginning_of_week was specified, returns :monday.
+ def beginning_of_week
+ Thread.current[:beginning_of_week] || beginning_of_week_default || :monday
+ end
+
+ # Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. :monday) for current request/thread.
+ #
+ # This method accepts any of the following day symbols:
+ # :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday
+ def beginning_of_week=(week_start)
+ Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
+ end
+
+ # Returns week start day symbol (e.g. :monday), or raises an ArgumentError for invalid day symbol.
+ def find_beginning_of_week!(week_start)
+ raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.keys.include?(week_start)
+ week_start
+ end
+
# Returns a new Date representing the date 1 day ago (i.e. yesterday's date).
def yesterday
::Date.current.yesterday
@@ -32,21 +48,6 @@ class Date
end
end
- # Returns true if the Date object's date lies in the past. Otherwise returns false.
- def past?
- self < ::Date.current
- end
-
- # Returns true if the Date object's date is today.
- def today?
- to_date == ::Date.current # we need the to_date because of DateTime
- end
-
- # Returns true if the Date object's date lies in the future.
- def future?
- self > ::Date.current
- end
-
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
# and then subtracts the specified number of seconds.
def ago(seconds)
@@ -106,9 +107,10 @@ class Date
end
# Returns a new Date where one or more of the elements have been changed according to the +options+ parameter.
+ # The +options+ parameter is a hash with a combination of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>.
#
- # Date.new(2007, 5, 12).change(:day => 1) # => Date.new(2007, 5, 1)
- # Date.new(2007, 5, 12).change(:year => 2005, :month => 1) # => Date.new(2005, 1, 12)
+ # Date.new(2007, 5, 12).change(day: 1) # => Date.new(2007, 5, 1)
+ # Date.new(2007, 5, 12).change(year: 2005, month: 1) # => Date.new(2005, 1, 12)
def change(options)
::Date.new(
options.fetch(:year, year),
@@ -116,161 +118,4 @@ class Date
options.fetch(:day, day)
)
end
-
- # Returns a new Date/DateTime representing the time a number of specified weeks ago.
- def weeks_ago(weeks)
- advance(:weeks => -weeks)
- end
-
- # Returns a new Date/DateTime representing the time a number of specified months ago.
- def months_ago(months)
- advance(:months => -months)
- end
-
- # Returns a new Date/DateTime representing the time a number of specified months in the future.
- def months_since(months)
- advance(:months => months)
- end
-
- # Returns a new Date/DateTime representing the time a number of specified years ago.
- def years_ago(years)
- advance(:years => -years)
- end
-
- # Returns a new Date/DateTime representing the time a number of specified years in the future.
- def years_since(years)
- advance(:years => years)
- end
-
- # Returns number of days to start of this week. Week is assumed to start on
- # +start_day+, default is +:monday+.
- def days_to_week_start(start_day = :monday)
- start_day_number = DAYS_INTO_WEEK[start_day]
- current_day_number = wday != 0 ? wday - 1 : 6
- (current_day_number - start_day_number) % 7
- end
-
- # Returns a new +Date+/+DateTime+ representing the start of this week. Week is
- # assumed to start on +start_day+, default is +:monday+. +DateTime+ objects
- # have their time set to 0:00.
- def beginning_of_week(start_day = :monday)
- days_to_start = days_to_week_start(start_day)
- result = self - days_to_start
- acts_like?(:time) ? result.midnight : result
- end
- alias :at_beginning_of_week :beginning_of_week
-
- # Returns a new +Date+/+DateTime+ representing the start of this week. Week is
- # assumed to start on a Monday. +DateTime+ objects have their time set to 0:00.
- def monday
- beginning_of_week
- end
-
- # Returns a new +Date+/+DateTime+ representing the end of this week. Week is
- # assumed to start on +start_day+, default is +:monday+. +DateTime+ objects
- # have their time set to 23:59:59.
- def end_of_week(start_day = :monday)
- days_to_end = 6 - days_to_week_start(start_day)
- result = self + days_to_end.days
- acts_like?(:time) ? result.end_of_day : result
- end
- alias :at_end_of_week :end_of_week
-
- # Returns a new +Date+/+DateTime+ representing the end of this week. Week is
- # assumed to start on a Monday. +DateTime+ objects have their time set to 23:59:59.
- def sunday
- end_of_week
- end
-
- # Returns a new +Date+/+DateTime+ representing the given +day+ in the previous
- # week. Default is +:monday+. +DateTime+ objects have their time set to 0:00.
- def prev_week(day = :monday)
- result = (self - 7).beginning_of_week + DAYS_INTO_WEEK[day]
- acts_like?(:time) ? result.change(:hour => 0) : result
- end
- alias :last_week :prev_week
-
- # Alias of prev_month
- alias :last_month :prev_month
-
- # Alias of prev_year
- alias :last_year :prev_year
-
- # Returns a new Date/DateTime representing the start of the given day in next week (default is :monday).
- def next_week(day = :monday)
- result = (self + 7).beginning_of_week + DAYS_INTO_WEEK[day]
- acts_like?(:time) ? result.change(:hour => 0) : result
- end
-
- # Short-hand for months_ago(3)
- def prev_quarter
- months_ago(3)
- end
- alias_method :last_quarter, :prev_quarter
-
- # Short-hand for months_since(3)
- def next_quarter
- months_since(3)
- end
-
- # Returns a new Date/DateTime representing the start of the month (1st of the month; DateTime objects will have time set to 0:00)
- def beginning_of_month
- acts_like?(:time) ? change(:day => 1, :hour => 0) : change(:day => 1)
- end
- alias :at_beginning_of_month :beginning_of_month
-
- # Returns a new Date/DateTime representing the end of the month (last day of the month; DateTime objects will have time set to 0:00)
- def end_of_month
- last_day = ::Time.days_in_month(month, year)
- if acts_like?(:time)
- change(:day => last_day, :hour => 23, :min => 59, :sec => 59)
- else
- change(:day => last_day)
- end
- end
- alias :at_end_of_month :end_of_month
-
- # Returns a new Date/DateTime representing the start of the quarter (1st of january, april, july, october; DateTime objects will have time set to 0:00)
- def beginning_of_quarter
- first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month }
- beginning_of_month.change(:month => first_quarter_month)
- end
- alias :at_beginning_of_quarter :beginning_of_quarter
-
- # Returns a new Date/DateTime representing the end of the quarter (last day of march, june, september, december; DateTime objects will have time set to 23:59:59)
- def end_of_quarter
- last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month }
- beginning_of_month.change(:month => last_quarter_month).end_of_month
- end
- alias :at_end_of_quarter :end_of_quarter
-
- # Returns a new Date/DateTime representing the start of the year (1st of january; DateTime objects will have time set to 0:00)
- def beginning_of_year
- if acts_like?(:time)
- change(:month => 1, :day => 1, :hour => 0)
- else
- change(:month => 1, :day => 1)
- end
- end
- alias :at_beginning_of_year :beginning_of_year
-
- # Returns a new Time representing the end of the year (31st of december; DateTime objects will have time set to 23:59:59)
- def end_of_year
- if acts_like?(:time)
- change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59)
- else
- change(:month => 12, :day => 31)
- end
- end
- alias :at_end_of_year :end_of_year
-
- # Convenience method which returns a new Date/DateTime representing the time 1 day ago
- def yesterday
- self - 1
- end
-
- # Convenience method which returns a new Date/DateTime representing the time 1 day since the instance time
- def tomorrow
- self + 1
- end
end
diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb
index 81f969e786..9120b0ba49 100644
--- a/activesupport/lib/active_support/core_ext/date/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date/conversions.rb
@@ -43,7 +43,7 @@ class Date
#
# # config/initializers/time_formats.rb
# Date::DATE_FORMATS[:month_and_year] = '%B %Y'
- # Date::DATE_FORMATS[:short_ordinal] = lambda { |date| date.strftime("%B #{date.day.ordinalize}") }
+ # Date::DATE_FORMATS[:short_ordinal] = ->(date) { date.strftime("%B #{date.day.ordinalize}") }
def to_formatted_s(format = :default)
if formatter = DATE_FORMATS[format]
if formatter.respond_to?(:call)
diff --git a/activesupport/lib/active_support/core_ext/date/zones.rb b/activesupport/lib/active_support/core_ext/date/zones.rb
index a70b47b7bc..c1b3934722 100644
--- a/activesupport/lib/active_support/core_ext/date/zones.rb
+++ b/activesupport/lib/active_support/core_ext/date/zones.rb
@@ -2,8 +2,9 @@ require 'date'
require 'active_support/core_ext/time/zones'
class Date
- # Converts Date to a TimeWithZone in the current zone if Time.zone or Time.zone_default
- # is set, otherwise converts Date to a Time via Date#to_time
+ # Converts Date to a TimeWithZone in the current zone if <tt>Time.zone</tt> or
+ # <tt>Time.zone_default</tt> is set, otherwise converts Date to a Time via
+ # Date#to_time.
def to_time_in_current_zone
if ::Time.zone
::Time.zone.local(year, month, day)
diff --git a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb
new file mode 100644
index 0000000000..1f78b9eb5a
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb
@@ -0,0 +1,232 @@
+module DateAndTime
+ module Calculations
+ DAYS_INTO_WEEK = {
+ :monday => 0,
+ :tuesday => 1,
+ :wednesday => 2,
+ :thursday => 3,
+ :friday => 4,
+ :saturday => 5,
+ :sunday => 6
+ }
+
+ # Returns a new date/time representing yesterday.
+ def yesterday
+ advance(:days => -1)
+ end
+
+ # Returns a new date/time representing tomorrow.
+ def tomorrow
+ advance(:days => 1)
+ end
+
+ # Returns true if the date/time is today.
+ def today?
+ to_date == ::Date.current
+ end
+
+ # Returns true if the date/time is in the past.
+ def past?
+ self < self.class.current
+ end
+
+ # Returns true if the date/time is in the future.
+ def future?
+ self > self.class.current
+ end
+
+ # Returns a new date/time the specified number of days ago.
+ def days_ago(days)
+ advance(:days => -days)
+ end
+
+ # Returns a new date/time the specified number of days in the future.
+ def days_since(days)
+ advance(:days => days)
+ end
+
+ # Returns a new date/time the specified number of weeks ago.
+ def weeks_ago(weeks)
+ advance(:weeks => -weeks)
+ end
+
+ # Returns a new date/time the specified number of weeks in the future.
+ def weeks_since(weeks)
+ advance(:weeks => weeks)
+ end
+
+ # Returns a new date/time the specified number of months ago.
+ def months_ago(months)
+ advance(:months => -months)
+ end
+
+ # Returns a new date/time the specified number of months in the future.
+ def months_since(months)
+ advance(:months => months)
+ end
+
+ # Returns a new date/time the specified number of years ago.
+ def years_ago(years)
+ advance(:years => -years)
+ end
+
+ # Returns a new date/time the specified number of years in the future.
+ def years_since(years)
+ advance(:years => years)
+ end
+
+ # Returns a new date/time at the start of the month.
+ # DateTime objects will have a time set to 0:00.
+ def beginning_of_month
+ first_hour{ change(:day => 1) }
+ end
+ alias :at_beginning_of_month :beginning_of_month
+
+ # Returns a new date/time at the start of the quarter.
+ # Example: 1st January, 1st July, 1st October.
+ # DateTime objects will have a time set to 0:00.
+ def beginning_of_quarter
+ first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month }
+ beginning_of_month.change(:month => first_quarter_month)
+ end
+ alias :at_beginning_of_quarter :beginning_of_quarter
+
+ # Returns a new date/time at the end of the quarter.
+ # Example: 31st March, 30th June, 30th September.
+ # DateTIme objects will have a time set to 23:59:59.
+ def end_of_quarter
+ last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month }
+ beginning_of_month.change(:month => last_quarter_month).end_of_month
+ end
+ alias :at_end_of_quarter :end_of_quarter
+
+ # Return a new date/time at the beginning of the year.
+ # Example: 1st January.
+ # DateTime objects will have a time set to 0:00.
+ def beginning_of_year
+ change(:month => 1).beginning_of_month
+ end
+ alias :at_beginning_of_year :beginning_of_year
+
+ # Returns a new date/time representing the given day in the next week.
+ # Week is assumed to start on +start_day+, default is
+ # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
+ # DateTime objects have their time set to 0:00.
+ def next_week(start_day = Date.beginning_of_week)
+ first_hour{ weeks_since(1).beginning_of_week.days_since(days_span(start_day)) }
+ end
+
+ # Short-hand for months_since(1).
+ def next_month
+ months_since(1)
+ end
+
+ # Short-hand for months_since(3)
+ def next_quarter
+ months_since(3)
+ end
+
+ # Short-hand for years_since(1).
+ def next_year
+ years_since(1)
+ end
+
+ # Returns a new date/time representing the given day in the previous week.
+ # Week is assumed to start on +start_day+, default is
+ # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
+ # DateTime objects have their time set to 0:00.
+ def prev_week(start_day = Date.beginning_of_week)
+ first_hour{ weeks_ago(1).beginning_of_week.days_since(days_span(start_day)) }
+ end
+ alias_method :last_week, :prev_week
+
+ # Short-hand for months_ago(1).
+ def prev_month
+ months_ago(1)
+ end
+ alias_method :last_month, :prev_month
+
+ # Short-hand for months_ago(3).
+ def prev_quarter
+ months_ago(3)
+ end
+ alias_method :last_quarter, :prev_quarter
+
+ # Short-hand for years_ago(1).
+ def prev_year
+ years_ago(1)
+ end
+ alias_method :last_year, :prev_year
+
+ # Returns the number of days to the start of the week on the given day.
+ # Week is assumed to start on +start_day+, default is
+ # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
+ def days_to_week_start(start_day = Date.beginning_of_week)
+ start_day_number = DAYS_INTO_WEEK[start_day]
+ current_day_number = wday != 0 ? wday - 1 : 6
+ (current_day_number - start_day_number) % 7
+ end
+
+ # Returns a new date/time representing the start of this week on the given day.
+ # Week is assumed to start on +start_day+, default is
+ # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
+ # +DateTime+ objects have their time set to 0:00.
+ def beginning_of_week(start_day = Date.beginning_of_week)
+ result = days_ago(days_to_week_start(start_day))
+ acts_like?(:time) ? result.midnight : result
+ end
+ alias :at_beginning_of_week :beginning_of_week
+
+ # Returns Monday of this week assuming that week starts on Monday.
+ # +DateTime+ objects have their time set to 0:00.
+ def monday
+ beginning_of_week(:monday)
+ end
+
+ # Returns a new date/time representing the end of this week on the given day.
+ # Week is assumed to start on +start_day+, default is
+ # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
+ # DateTime objects have their time set to 23:59:59.
+ def end_of_week(start_day = Date.beginning_of_week)
+ last_hour{ days_since(6 - days_to_week_start(start_day)) }
+ end
+ alias :at_end_of_week :end_of_week
+
+ # Returns Sunday of this week assuming that week starts on Monday.
+ # +DateTime+ objects have their time set to 23:59:59.
+ def sunday
+ end_of_week(:monday)
+ end
+
+ # Returns a new date/time representing the end of the month.
+ # DateTime objects will have a time set to 23:59:59.
+ def end_of_month
+ last_day = ::Time.days_in_month(month, year)
+ last_hour{ days_since(last_day - day) }
+ end
+ alias :at_end_of_month :end_of_month
+
+ # Returns a new date/time representing the end of the year.
+ # DateTime objects will have a time set to 23:59:59.
+ def end_of_year
+ change(:month => 12).end_of_month
+ end
+ alias :at_end_of_year :end_of_year
+
+ private
+
+ def first_hour
+ result = yield
+ acts_like?(:time) ? result.change(:hour => 0) : result
+ end
+
+ def last_hour
+ result = yield
+ acts_like?(:time) ? result.end_of_day : result
+ end
+
+ def days_span(day)
+ (DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
+ end
+ end
+end
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 fd78044b5d..385aa586bb 100644
--- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb
@@ -9,30 +9,40 @@ class DateTime
::Time.local(2012).utc_offset.to_r / 86400
end
- # Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise returns <tt>Time.now.to_datetime</tt>.
+ # Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or
+ # <tt>config.time_zone</tt> are set, otherwise returns
+ # <tt>Time.now.to_datetime</tt>.
def current
::Time.zone ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime
end
end
- # Tells whether the DateTime object's datetime lies in the past
+ # Tells whether the DateTime object's datetime lies in the past.
def past?
self < ::DateTime.current
end
- # Tells whether the DateTime object's datetime lies in the future
+ # Tells whether the DateTime object's datetime lies in the future.
def future?
self > ::DateTime.current
end
- # Seconds since midnight: DateTime.now.seconds_since_midnight
+ # Seconds since midnight: DateTime.now.seconds_since_midnight.
def seconds_since_midnight
sec + (min * 60) + (hour * 3600)
end
- # Returns a new DateTime where one or more of the elements have been changed according to the +options+ parameter. The time options
- # (hour, minute, sec) reset cascadingly, so if only the hour is passed, then minute and sec is set to 0. If the hour and
- # minute is passed, then sec is set to 0.
+ # 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
+ # passed, then minute and sec is set to 0. If the hour and minute is passed,
+ # then sec is set to 0. The +options+ parameter takes a hash with any of these
+ # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>,
+ # <tt>:min</tt>, <tt>:sec</tt>, <tt>:offset</tt>, <tt>:start</tt>.
+ #
+ # DateTime.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => DateTime.new(2012, 8, 1, 22, 35, 0)
+ # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => DateTime.new(1981, 8, 1, 22, 35, 0)
+ # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0)
def change(options)
::DateTime.civil(
options.fetch(:year, year),
@@ -65,20 +75,21 @@ class DateTime
end
end
- # Returns a new DateTime representing the time a number of seconds ago
+ # Returns a new DateTime representing the time a number of seconds ago.
# Do not use this method in combination with x.months, use months_ago instead!
def ago(seconds)
since(-seconds)
end
- # Returns a new DateTime representing the time a number of seconds since the instance time
- # Do not use this method in combination with x.months, use months_since instead!
+ # Returns a new DateTime representing the time a number of seconds since the
+ # instance time. Do not use this method in combination with x.months, use
+ # months_since instead!
def since(seconds)
self + Rational(seconds.round, 86400)
end
alias :in :since
- # Returns a new DateTime representing the start of the day (0:00)
+ # Returns a new DateTime representing the start of the day (0:00).
def beginning_of_day
change(:hour => 0)
end
@@ -86,42 +97,43 @@ class DateTime
alias :at_midnight :beginning_of_day
alias :at_beginning_of_day :beginning_of_day
- # Returns a new DateTime representing the end of the day (23:59:59)
+ # Returns a new DateTime representing the end of the day (23:59:59).
def end_of_day
change(:hour => 23, :min => 59, :sec => 59)
end
- # Returns a new DateTime representing the start of the hour (hh:00:00)
+ # Returns a new DateTime representing the start of the hour (hh:00:00).
def beginning_of_hour
change(:min => 0)
end
alias :at_beginning_of_hour :beginning_of_hour
- # Returns a new DateTime representing the end of the hour (hh:59:59)
+ # Returns a new DateTime representing the end of the hour (hh:59:59).
def end_of_hour
change(:min => 59, :sec => 59)
end
- # Adjusts DateTime to UTC by adding its offset value; offset is set to 0
+ # Adjusts DateTime to UTC by adding its offset value; offset is set to 0.
#
- # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
- # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000
+ # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
+ # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000
def utc
new_offset(0)
end
alias_method :getutc, :utc
- # Returns true if offset == 0
+ # Returns +true+ if <tt>offset == 0</tt>.
def utc?
offset == 0
end
- # Returns the offset value in seconds
+ # Returns the offset value in seconds.
def utc_offset
(offset * 86400).to_i
end
- # Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTime
+ # Layers additional behavior on DateTime#<=> so that Time and
+ # ActiveSupport::TimeWithZone instances can be compared with a DateTime.
def <=>(other)
super other.to_datetime
end
diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
index 7c3a5eaace..b7d8414a9d 100644
--- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
@@ -53,7 +53,8 @@ class DateTime
alias_method :default_inspect, :inspect
alias_method :inspect, :readable_inspect
- # Returns DateTime with local offset for given year if format is local else offset is zero
+ # Returns DateTime with local offset for given year if format is local else
+ # offset is zero.
#
# DateTime.civil_from_format :local, 2012
# # => Sun, 01 Jan 2012 00:00:00 +0300
@@ -68,12 +69,12 @@ class DateTime
civil(year, month, day, hour, min, sec, offset)
end
- # Converts self to a floating-point number of seconds since the Unix epoch.
+ # Converts +self+ to a floating-point number of seconds since the Unix epoch.
def to_f
seconds_since_unix_epoch.to_f
end
- # Converts self to an integer number of seconds since the Unix epoch.
+ # Converts +self+ to an integer number of seconds since the Unix epoch.
def to_i
seconds_since_unix_epoch.to_i
end
diff --git a/activesupport/lib/active_support/core_ext/date_time/zones.rb b/activesupport/lib/active_support/core_ext/date_time/zones.rb
index 823735d3e2..6457ffbaf6 100644
--- a/activesupport/lib/active_support/core_ext/date_time/zones.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/zones.rb
@@ -6,13 +6,14 @@ class DateTime
# Time.zone = 'Hawaii' # => 'Hawaii'
# DateTime.new(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
#
- # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
- # instead of the operating system's time zone.
+ # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt>
+ # as the local zone instead of the operating system's time zone.
#
- # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
- # and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
+ # You can also pass in a TimeZone instance or string that identifies a TimeZone
+ # as an argument, and the conversion will be based on that zone instead of
+ # <tt>Time.zone</tt>.
#
- # DateTime.new(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
+ # DateTime.new(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
def in_time_zone(zone = ::Time.zone)
if zone
ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone))
diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb
index 03efe6a19a..4501b7ff58 100644
--- a/activesupport/lib/active_support/core_ext/enumerable.rb
+++ b/activesupport/lib/active_support/core_ext/enumerable.rb
@@ -17,7 +17,6 @@ module Enumerable
# The default sum of an empty list is zero. You can override this default:
#
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
- #
def sum(identity = 0, &block)
if block_given?
map(&block).sum(identity)
@@ -32,7 +31,6 @@ module Enumerable
# => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
# people.index_by { |person| "#{person.first_name} #{person.last_name}" }
# => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
- #
def index_by
if block_given?
Hash[map { |elem| [yield(elem), elem] }]
@@ -41,8 +39,10 @@ module Enumerable
end
end
- # Returns true if the enumerable has more than 1 element. Functionally equivalent to enum.to_a.size > 1.
- # Can be called with a block too, much like any?, so <tt>people.many? { |p| p.age > 26 }</tt> returns true if more than one person is over 26.
+ # Returns +true+ if the enumerable has more than 1 element. Functionally
+ # equivalent to <tt>enum.to_a.size > 1</tt>. Can be called with a block too,
+ # much like any?, so <tt>people.many? { |p| p.age > 26 }</tt> returns +true+
+ # if more than one person is over 26.
def many?
cnt = 0
if block_given?
@@ -55,7 +55,8 @@ module Enumerable
end
end
- # The negative of the <tt>Enumerable#include?</tt>. Returns true if the collection does not include the object.
+ # The negative of the <tt>Enumerable#include?</tt>. Returns +true+ if the
+ # collection does not include the object.
def exclude?(object)
!include?(object)
end
diff --git a/activesupport/lib/active_support/core_ext/file/atomic.rb b/activesupport/lib/active_support/core_ext/file/atomic.rb
index 9e504851e7..81beb4e85d 100644
--- a/activesupport/lib/active_support/core_ext/file/atomic.rb
+++ b/activesupport/lib/active_support/core_ext/file/atomic.rb
@@ -1,3 +1,5 @@
+require 'fileutils'
+
class File
# Write to a file atomically. Useful for situations where you don't
# want other processes or threads to see half-written files.
@@ -25,17 +27,9 @@ class File
# Get original file permissions
old_stat = stat(file_name)
rescue Errno::ENOENT
- # No old permissions, write a temp file to determine the defaults
- temp_file_name = [
- '.permissions_check',
- Thread.current.object_id,
- Process.pid,
- rand(1000000)
- ].join('.')
- check_name = join(dirname(file_name), temp_file_name)
- open(check_name, 'w') { }
- old_stat = stat(check_name)
- unlink(check_name)
+ # If not possible, probe which are the default permissions in the
+ # destination directory.
+ old_stat = probe_stat_in(dirname(file_name))
end
# Overwrite original file with temp file
@@ -45,4 +39,20 @@ class File
chown(old_stat.uid, old_stat.gid, file_name)
chmod(old_stat.mode, file_name)
end
+
+ # Private utility method.
+ def self.probe_stat_in(dir) #:nodoc:
+ basename = [
+ '.permissions_check',
+ Thread.current.object_id,
+ Process.pid,
+ rand(1000000)
+ ].join('.')
+
+ file_name = join(dir, basename)
+ FileUtils.touch(file_name)
+ stat(file_name)
+ ensure
+ FileUtils.rm_f(file_name) if file_name
+ end
end
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
index 7c72ead36c..5ba8197006 100644
--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -40,7 +40,7 @@ class Hash
# end
# end
#
- # {:foo => Foo.new}.to_xml(:skip_instruct => true)
+ # { foo: Foo.new }.to_xml(skip_instruct: true)
# # => "<hash><bar>fooing!</bar></hash>"
#
# * Otherwise, a node with +key+ as tag is created with a string representation of
diff --git a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
index 023bf68a87..83f0c87b04 100644
--- a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
+++ b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
@@ -1,20 +1,26 @@
class Hash
# Returns a new hash with +self+ and +other_hash+ merged recursively.
#
- # h1 = {x: {y: [4,5,6]}, z: [7,8,9]}
- # h2 = {x: {y: [7,8,9]}, z: "xyz"}
+ # h1 = { x: { y: [4,5,6] }, z: [7,8,9] }
+ # h2 = { x: { y: [7,8,9] }, z: 'xyz' }
#
# h1.deep_merge(h2) #=> {:x => {:y => [7, 8, 9]}, :z => "xyz"}
# h2.deep_merge(h1) #=> {:x => {:y => [4, 5, 6]}, :z => [7, 8, 9]}
- def deep_merge(other_hash)
- dup.deep_merge!(other_hash)
+ # h1.deep_merge(h2) { |key, old, new| Array.wrap(old) + Array.wrap(new) }
+ # #=> {:x => {:y => [4, 5, 6, 7, 8, 9]}, :z => [7, 8, 9, "xyz"]}
+ def deep_merge(other_hash, &block)
+ dup.deep_merge!(other_hash, &block)
end
# Same as +deep_merge+, but modifies +self+.
- def deep_merge!(other_hash)
+ def deep_merge!(other_hash, &block)
other_hash.each_pair do |k,v|
tv = self[k]
- self[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_merge(v) : v
+ if tv.is_a?(Hash) && v.is_a?(Hash)
+ self[k] = tv.deep_merge(v, &block)
+ else
+ self[k] = block && tv ? block.call(k, tv, v) : v
+ end
end
self
end
diff --git a/activesupport/lib/active_support/core_ext/hash/except.rb b/activesupport/lib/active_support/core_ext/hash/except.rb
index c82da3c6c2..5cb00d0ebd 100644
--- a/activesupport/lib/active_support/core_ext/hash/except.rb
+++ b/activesupport/lib/active_support/core_ext/hash/except.rb
@@ -3,7 +3,6 @@ class Hash
# limiting a set of parameters to everything but a few known toggles:
#
# @person.update_attributes(params[:person].except(:admin))
- #
def except(*keys)
dup.except!(*keys)
end
diff --git a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
index 7d54c9fae6..6c7e876fca 100644
--- a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
+++ b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
@@ -4,8 +4,7 @@ class Hash
# Returns an <tt>ActiveSupport::HashWithIndifferentAccess</tt> out of its receiver:
#
- # {:a => 1}.with_indifferent_access["a"] # => 1
- #
+ # { a: 1 }.with_indifferent_access['a'] # => 1
def with_indifferent_access
ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self)
end
@@ -17,8 +16,7 @@ class Hash
# converting to an <tt>ActiveSupport::HashWithIndifferentAccess</tt> would not be
# desirable.
#
- # b = {:b => 1}
- # {:a => b}.with_indifferent_access["a"] # calls b.nested_under_indifferent_access
- #
+ # b = { b: 1 }
+ # { a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access
alias nested_under_indifferent_access with_indifferent_access
end
diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb
index e753e36124..13081995b0 100644
--- a/activesupport/lib/active_support/core_ext/hash/keys.rb
+++ b/activesupport/lib/active_support/core_ext/hash/keys.rb
@@ -14,7 +14,7 @@ class Hash
end
# Destructively convert all keys using the block operations.
- # Same as transform_keys but modifies +self+
+ # Same as transform_keys but modifies +self+.
def transform_keys!
keys.each do |key|
self[yield(key)] = delete(key)
@@ -57,13 +57,13 @@ class Hash
end
alias_method :to_options!, :symbolize_keys!
- # Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch.
- # Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols
- # as keys, this will fail.
+ # Validate all keys in a hash match <tt>*valid_keys</tt>, raising ArgumentError
+ # on a mismatch. Note that keys are NOT treated indifferently, meaning if you
+ # use strings for keys but assert symbols as keys, this will fail.
#
- # { :name => 'Rob', :years => '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: years"
- # { :name => 'Rob', :age => '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: name"
- # { :name => 'Rob', :age => '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing
+ # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: years"
+ # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: name"
+ # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing
def assert_valid_keys(*valid_keys)
valid_keys.flatten!
each_key do |k|
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 6074103484..fbb482435d 100644
--- a/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb
+++ b/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb
@@ -1,11 +1,11 @@
class Hash
# Merges the caller into +other_hash+. For example,
#
- # options = options.reverse_merge(:size => 25, :velocity => 10)
+ # options = options.reverse_merge(size: 25, velocity: 10)
#
# is equivalent to
#
- # options = {:size => 25, :velocity => 10}.merge(options)
+ # options = { size: 25, velocity: 10 }.merge(options)
#
# This is particularly useful for initializing an options hash
# with default values.
diff --git a/activesupport/lib/active_support/core_ext/hash/slice.rb b/activesupport/lib/active_support/core_ext/hash/slice.rb
index b862b5ae2a..45fec57009 100644
--- a/activesupport/lib/active_support/core_ext/hash/slice.rb
+++ b/activesupport/lib/active_support/core_ext/hash/slice.rb
@@ -3,7 +3,7 @@ class Hash
# limiting an options hash to valid keys before passing to a method:
#
# def search(criteria = {})
- # assert_valid_keys(:mass, :velocity, :time)
+ # criteria.assert_valid_keys(:mass, :velocity, :time)
# end
#
# search(options.slice(:mass, :velocity, :time))
@@ -19,7 +19,9 @@ class Hash
# Replaces the hash with only the given keys.
# Returns a hash containing the removed key/value pairs.
- # {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d => 4}
+ #
+ # { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
+ # # => {:c => 3, :d => 4}
def slice!(*keys)
keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
omit = slice(*self.keys - keys)
@@ -29,7 +31,9 @@ class Hash
end
# Removes and returns the key/value pairs matching the given keys.
- # {:a => 1, :b => 2, :c => 3, :d => 4}.extract!(:a, :b) # => {:a => 1, :b => 2}
+ #
+ # { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b)
+ # # => {:a => 1, :b => 2}
def extract!(*keys)
keys.each_with_object({}) { |key, result| result[key] = delete(key) }
end
diff --git a/activesupport/lib/active_support/core_ext/integer/inflections.rb b/activesupport/lib/active_support/core_ext/integer/inflections.rb
index 1e30687166..56f2ed5985 100644
--- a/activesupport/lib/active_support/core_ext/integer/inflections.rb
+++ b/activesupport/lib/active_support/core_ext/integer/inflections.rb
@@ -10,7 +10,6 @@ class Integer
# 1003.ordinalize # => "1003rd"
# -11.ordinalize # => "-11th"
# -1001.ordinalize # => "-1001st"
- #
def ordinalize
ActiveSupport::Inflector.ordinalize(self)
end
@@ -24,7 +23,6 @@ class Integer
# 1003.ordinal # => "rd"
# -11.ordinal # => "th"
# -1001.ordinal # => "st"
- #
def ordinal
ActiveSupport::Inflector.ordinal(self)
end
diff --git a/activesupport/lib/active_support/core_ext/integer/time.rb b/activesupport/lib/active_support/core_ext/integer/time.rb
index 894b5d0696..9fb4f6b73a 100644
--- a/activesupport/lib/active_support/core_ext/integer/time.rb
+++ b/activesupport/lib/active_support/core_ext/integer/time.rb
@@ -1,21 +1,23 @@
class Integer
- # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
+ # Enables the use of time calculations and declarations, like <tt>45.minutes +
+ # 2.hours + 4.years</tt>.
#
- # These methods use Time#advance for precise date calculations when using from_now, ago, etc.
- # as well as adding or subtracting their results from a Time object. For example:
+ # These methods use Time#advance for precise date calculations when using
+ # <tt>from_now</tt>, +ago+, etc. as well as adding or subtracting their
+ # results from a Time object.
#
- # # equivalent to Time.now.advance(:months => 1)
+ # # equivalent to Time.now.advance(months: 1)
# 1.month.from_now
#
- # # equivalent to Time.now.advance(:years => 2)
+ # # equivalent to Time.now.advance(years: 2)
# 2.years.from_now
#
- # # equivalent to Time.now.advance(:months => 4, :years => 5)
+ # # equivalent to Time.now.advance(months: 4, years: 5)
# (4.months + 5.years).from_now
#
- # While these methods provide precise calculation when used as in the examples above, care
- # should be taken to note that this is not true if the result of `months', `years', etc is
- # converted before use:
+ # While these methods provide precise calculation when used as in the examples
+ # above, care should be taken to note that this is not true if the result of
+ # +months+, +years+, etc is converted before use:
#
# # equivalent to 30.days.to_i.from_now
# 1.month.to_i.from_now
diff --git a/activesupport/lib/active_support/core_ext/kernel/reporting.rb b/activesupport/lib/active_support/core_ext/kernel/reporting.rb
index ad3f9ebec9..bc97da6ef2 100644
--- a/activesupport/lib/active_support/core_ext/kernel/reporting.rb
+++ b/activesupport/lib/active_support/core_ext/kernel/reporting.rb
@@ -1,7 +1,8 @@
require 'rbconfig'
module Kernel
- # Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards.
+ # Sets $VERBOSE to nil for the duration of the block and back to its original
+ # value afterwards.
#
# silence_warnings do
# value = noisy_call # no warning voiced
@@ -12,12 +13,14 @@ module Kernel
with_warnings(nil) { yield }
end
- # Sets $VERBOSE to true for the duration of the block and back to its original value afterwards.
+ # Sets $VERBOSE to +true+ for the duration of the block and back to its
+ # original value afterwards.
def enable_warnings
with_warnings(true) { yield }
end
- # Sets $VERBOSE for the duration of the block and back to its original value afterwards.
+ # Sets $VERBOSE for the duration of the block and back to its original
+ # value afterwards.
def with_warnings(flag)
old_verbose, $VERBOSE = $VERBOSE, flag
yield
@@ -65,7 +68,6 @@ module Kernel
#
# stream = capture(:stdout) { puts 'Cool' }
# stream # => "Cool\n"
- #
def capture(stream)
begin
stream = stream.to_s
@@ -83,7 +85,6 @@ module Kernel
# Silences both STDOUT and STDERR, even for subprocesses.
#
# quietly { system 'bundle install' }
- #
def quietly
silence_stream(STDOUT) do
silence_stream(STDERR) do
diff --git a/activesupport/lib/active_support/core_ext/module/anonymous.rb b/activesupport/lib/active_support/core_ext/module/anonymous.rb
index 0a9e791030..b0c7b021db 100644
--- a/activesupport/lib/active_support/core_ext/module/anonymous.rb
+++ b/activesupport/lib/active_support/core_ext/module/anonymous.rb
@@ -13,7 +13,6 @@ class Module
# m = Module.new # creates an anonymous module
# M = m # => m gets a name here as a side-effect
# m.name # => "M"
- #
def anonymous?
name.nil?
end
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index 39a1240c61..e608eeaf42 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -18,7 +18,7 @@ class Module
#
# class Foo < ActiveRecord::Base
# belongs_to :greeter
- # delegate :hello, :to => :greeter
+ # delegate :hello, to: :greeter
# end
#
# Foo.new.hello # => "hello"
@@ -28,7 +28,7 @@ class Module
#
# class Foo < ActiveRecord::Base
# belongs_to :greeter
- # delegate :hello, :goodbye, :to => :greeter
+ # delegate :hello, :goodbye, to: :greeter
# end
#
# Foo.new.goodbye # => "goodbye"
@@ -43,15 +43,27 @@ class Module
# def initialize
# @instance_array = [8,9,10,11]
# end
- # delegate :sum, :to => :CONSTANT_ARRAY
- # delegate :min, :to => :@@class_array
- # delegate :max, :to => :@instance_array
+ # delegate :sum, to: :CONSTANT_ARRAY
+ # delegate :min, to: :@@class_array
+ # delegate :max, to: :@instance_array
# end
#
# Foo.new.sum # => 6
# Foo.new.min # => 4
# Foo.new.max # => 11
#
+ # It's also possible to delegate a method to the class by using +:class+:
+ #
+ # class Foo
+ # def self.hello
+ # "world"
+ # end
+ #
+ # delegate :hello, to: :class
+ # end
+ #
+ # Foo.new.hello # => "world"
+ #
# Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value
# is <tt>true</tt>, the delegate methods are prefixed with the name of the object being
# delegated to.
@@ -59,7 +71,7 @@ class Module
# Person = Struct.new(:name, :address)
#
# class Invoice < Struct.new(:client)
- # delegate :name, :address, :to => :client, :prefix => true
+ # delegate :name, :address, to: :client, prefix: true
# end
#
# john_doe = Person.new('John Doe', 'Vimmersvej 13')
@@ -70,7 +82,7 @@ class Module
# It is also possible to supply a custom prefix.
#
# class Invoice < Struct.new(:client)
- # delegate :name, :address, :to => :client, :prefix => :customer
+ # delegate :name, :address, to: :client, prefix: :customer
# end
#
# invoice = Invoice.new(john_doe)
@@ -86,7 +98,7 @@ class Module
# def initialize(bar = nil)
# @bar = bar
# end
- # delegate :zoo, :to => :bar
+ # delegate :zoo, to: :bar
# end
#
# Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
@@ -96,15 +108,14 @@ class Module
# def initialize(bar = nil)
# @bar = bar
# end
- # delegate :zoo, :to => :bar, :allow_nil => true
+ # delegate :zoo, to: :bar, allow_nil: true
# end
#
# Foo.new.zoo # returns nil
- #
def delegate(*methods)
options = methods.pop
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).'
+ 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, allow_nil = options.values_at(:prefix, :allow_nil)
@@ -123,6 +134,9 @@ class Module
file, line = caller.first.split(':', 2)
line = line.to_i
+ to = to.to_s
+ to = 'self.class' if to == 'class'
+
methods.each do |method|
# Attribute writer methods only accept one argument. Makes sure []=
# methods still accept two arguments.
diff --git a/activesupport/lib/active_support/core_ext/module/deprecation.rb b/activesupport/lib/active_support/core_ext/module/deprecation.rb
index 9e77ac3c45..34ec6a3d8f 100644
--- a/activesupport/lib/active_support/core_ext/module/deprecation.rb
+++ b/activesupport/lib/active_support/core_ext/module/deprecation.rb
@@ -1,10 +1,24 @@
require 'active_support/deprecation/method_wrappers'
class Module
- # Declare that a method has been deprecated.
# deprecate :foo
# deprecate :bar => 'message'
# deprecate :foo, :bar, :baz => 'warning!', :qux => 'gone!'
+ #
+ # You can also use custom deprecator instance:
+ #
+ # deprecate :foo, :deprecator => MyLib::Deprecator.new
+ # deprecate :foo, :bar => "warning!", :deprecator => MyLib::Deprecator.new
+ #
+ # \Custom deprecators must respond to <tt>deprecation_warning(deprecated_method_name, message, caller_backtrace)</tt>
+ # method where you can implement your custom warning behavior.
+ #
+ # class MyLib::Deprecator
+ # def deprecation_warning(deprecated_method_name, message, caller_backtrace)
+ # message = "#{method_name} is deprecated and will be removed from MyLibrary | #{message}"
+ # Kernel.warn message
+ # end
+ # end
def deprecate(*method_names)
ActiveSupport::Deprecation.deprecate_methods(self, *method_names)
end
diff --git a/activesupport/lib/active_support/core_ext/module/introspection.rb b/activesupport/lib/active_support/core_ext/module/introspection.rb
index 3c8e811fa4..649a969149 100644
--- a/activesupport/lib/active_support/core_ext/module/introspection.rb
+++ b/activesupport/lib/active_support/core_ext/module/introspection.rb
@@ -27,7 +27,6 @@ class Module
#
# M.parent # => Object
# Module.new.parent # => Object
- #
def parent
parent_name ? ActiveSupport::Inflector.constantize(parent_name) : Object
end
@@ -44,7 +43,6 @@ class Module
# M.parents # => [Object]
# M::N.parents # => [M, Object]
# X.parents # => [M, Object]
- #
def parents
parents = []
if parent_name
diff --git a/activesupport/lib/active_support/core_ext/numeric/conversions.rb b/activesupport/lib/active_support/core_ext/numeric/conversions.rb
index 2bbfa78639..6d3635c69a 100644
--- a/activesupport/lib/active_support/core_ext/numeric/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/numeric/conversions.rb
@@ -14,89 +14,89 @@ class Numeric
# ==== Examples
#
# Phone Numbers:
- # 5551234.to_s(:phone) # => 555-1234
- # 1235551234.to_s(:phone) # => 123-555-1234
- # 1235551234.to_s(:phone, :area_code => true) # => (123) 555-1234
- # 1235551234.to_s(:phone, :delimiter => " ") # => 123 555 1234
- # 1235551234.to_s(:phone, :area_code => true, :extension => 555) # => (123) 555-1234 x 555
- # 1235551234.to_s(:phone, :country_code => 1) # => +1-123-555-1234
- # 1235551234.to_s(:phone, :country_code => 1, :extension => 1343, :delimiter => ".")
+ # 5551234.to_s(:phone) # => 555-1234
+ # 1235551234.to_s(:phone) # => 123-555-1234
+ # 1235551234.to_s(:phone, area_code: true) # => (123) 555-1234
+ # 1235551234.to_s(:phone, delimiter: ' ') # => 123 555 1234
+ # 1235551234.to_s(:phone, area_code: true, extension: 555) # => (123) 555-1234 x 555
+ # 1235551234.to_s(:phone, country_code: 1) # => +1-123-555-1234
+ # 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
# # => +1.123.555.1234 x 1343
#
# Currency:
- # 1234567890.50.to_s(:currency) # => $1,234,567,890.50
- # 1234567890.506.to_s(:currency) # => $1,234,567,890.51
- # 1234567890.506.to_s(:currency, :precision => 3) # => $1,234,567,890.506
- # 1234567890.506.to_s(:currency, :locale => :fr) # => 1 234 567 890,51 €
- # -1234567890.50.to_s(:currency, :negative_format => "(%u%n)")
+ # 1234567890.50.to_s(:currency) # => $1,234,567,890.50
+ # 1234567890.506.to_s(:currency) # => $1,234,567,890.51
+ # 1234567890.506.to_s(:currency, precision: 3) # => $1,234,567,890.506
+ # 1234567890.506.to_s(:currency, locale: :fr) # => 1 234 567 890,51 €
+ # -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
# # => ($1,234,567,890.50)
- # 1234567890.50.to_s(:currency, :unit => "&pound;", :separator => ",", :delimiter => "")
+ # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '')
# # => &pound;1234567890,50
- # 1234567890.50.to_s(:currency, :unit => "&pound;", :separator => ",", :delimiter => "", :format => "%n %u")
+ # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
# # => 1234567890,50 &pound;
#
# Percentage:
- # 100.to_s(:percentage) # => 100.000%
- # 100.to_s(:percentage, :precision => 0) # => 100%
- # 1000.to_s(:percentage, :delimiter => '.', :separator => ',') # => 1.000,000%
- # 302.24398923423.to_s(:percentage, :precision => 5) # => 302.24399%
- # 1000.to_s(:percentage, :locale => :fr) # => 1 000,000%
- # 100.to_s(:percentage, :format => "%n %") # => 100 %
+ # 100.to_s(:percentage) # => 100.000%
+ # 100.to_s(:percentage, precision: 0) # => 100%
+ # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => 1.000,000%
+ # 302.24398923423.to_s(:percentage, precision: 5) # => 302.24399%
+ # 1000.to_s(:percentage, locale: :fr) # => 1 000,000%
+ # 100.to_s(:percentage, format: '%n %') # => 100 %
#
# Delimited:
- # 12345678.to_s(:delimited) # => 12,345,678
- # 12345678.05.to_s(:delimited) # => 12,345,678.05
- # 12345678.to_s(:delimited, :delimiter => ".") # => 12.345.678
- # 12345678.to_s(:delimited, :delimiter => ",") # => 12,345,678
- # 12345678.05.to_s(:delimited, :separator => " ") # => 12,345,678 05
- # 12345678.05.to_s(:delimited, :locale => :fr) # => 12 345 678,05
- # 98765432.98.to_s(:delimited, :delimiter => " ", :separator => ",")
+ # 12345678.to_s(:delimited) # => 12,345,678
+ # 12345678.05.to_s(:delimited) # => 12,345,678.05
+ # 12345678.to_s(:delimited, delimiter: '.') # => 12.345.678
+ # 12345678.to_s(:delimited, delimiter: ',') # => 12,345,678
+ # 12345678.05.to_s(:delimited, separator: ' ') # => 12,345,678 05
+ # 12345678.05.to_s(:delimited, locale: :fr) # => 12 345 678,05
+ # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
# # => 98 765 432,98
#
# Rounded:
- # 111.2345.to_s(:rounded) # => 111.235
- # 111.2345.to_s(:rounded, :precision => 2) # => 111.23
- # 13.to_s(:rounded, :precision => 5) # => 13.00000
- # 389.32314.to_s(:rounded, :precision => 0) # => 389
- # 111.2345.to_s(:rounded, :significant => true) # => 111
- # 111.2345.to_s(:rounded, :precision => 1, :significant => true) # => 100
- # 13.to_s(:rounded, :precision => 5, :significant => true) # => 13.000
- # 111.234.to_s(:rounded, :locale => :fr) # => 111,234
- # 13.to_s(:rounded, :precision => 5, :significant => true, :strip_insignificant_zeros => true)
+ # 111.2345.to_s(:rounded) # => 111.235
+ # 111.2345.to_s(:rounded, precision: 2) # => 111.23
+ # 13.to_s(:rounded, precision: 5) # => 13.00000
+ # 389.32314.to_s(:rounded, precision: 0) # => 389
+ # 111.2345.to_s(:rounded, significant: true) # => 111
+ # 111.2345.to_s(:rounded, precision: 1, significant: true) # => 100
+ # 13.to_s(:rounded, precision: 5, significant: true) # => 13.000
+ # 111.234.to_s(:rounded, locale: :fr) # => 111,234
+ # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
# # => 13
- # 389.32314.to_s(:rounded, :precision => 4, :significant => true) # => 389.3
- # 1111.2345.to_s(:rounded, :precision => 2, :separator => ',', :delimiter => '.')
+ # 389.32314.to_s(:rounded, precision: 4, significant: true) # => 389.3
+ # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
# # => 1.111,23
#
# Human-friendly size in Bytes:
- # 123.to_s(:human_size) # => 123 Bytes
- # 1234.to_s(:human_size) # => 1.21 KB
- # 12345.to_s(:human_size) # => 12.1 KB
- # 1234567.to_s(:human_size) # => 1.18 MB
- # 1234567890.to_s(:human_size) # => 1.15 GB
- # 1234567890123.to_s(:human_size) # => 1.12 TB
- # 1234567.to_s(:human_size, :precision => 2) # => 1.2 MB
- # 483989.to_s(:human_size, :precision => 2) # => 470 KB
- # 1234567.to_s(:human_size, :precision => 2, :separator => ',') # => 1,2 MB
- # 1234567890123.to_s(:human_size, :precision => 5) # => "1.1229 TB"
- # 524288000.to_s(:human_size, :precision => 5) # => "500 MB"
+ # 123.to_s(:human_size) # => 123 Bytes
+ # 1234.to_s(:human_size) # => 1.21 KB
+ # 12345.to_s(:human_size) # => 12.1 KB
+ # 1234567.to_s(:human_size) # => 1.18 MB
+ # 1234567890.to_s(:human_size) # => 1.15 GB
+ # 1234567890123.to_s(:human_size) # => 1.12 TB
+ # 1234567.to_s(:human_size, precision: 2) # => 1.2 MB
+ # 483989.to_s(:human_size, precision: 2) # => 470 KB
+ # 1234567.to_s(:human_size, precision: 2, separator: ',') # => 1,2 MB
+ # 1234567890123.to_s(:human_size, precision: 5) # => "1.1229 TB"
+ # 524288000.to_s(:human_size, precision: 5) # => "500 MB"
#
# Human-friendly format:
- # 123.to_s(:human) # => "123"
- # 1234.to_s(:human) # => "1.23 Thousand"
- # 12345.to_s(:human) # => "12.3 Thousand"
- # 1234567.to_s(:human) # => "1.23 Million"
- # 1234567890.to_s(:human) # => "1.23 Billion"
- # 1234567890123.to_s(:human) # => "1.23 Trillion"
- # 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
- # 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
- # 489939.to_s(:human, :precision => 2) # => "490 Thousand"
- # 489939.to_s(:human, :precision => 4) # => "489.9 Thousand"
- # 1234567.to_s(:human, :precision => 4,
- # :significant => false) # => "1.2346 Million"
- # 1234567.to_s(:human, :precision => 1,
- # :separator => ',',
- # :significant => false) # => "1,2 Million"
+ # 123.to_s(:human) # => "123"
+ # 1234.to_s(:human) # => "1.23 Thousand"
+ # 12345.to_s(:human) # => "12.3 Thousand"
+ # 1234567.to_s(:human) # => "1.23 Million"
+ # 1234567890.to_s(:human) # => "1.23 Billion"
+ # 1234567890123.to_s(:human) # => "1.23 Trillion"
+ # 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
+ # 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
+ # 489939.to_s(:human, precision: 2) # => "490 Thousand"
+ # 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
+ # 1234567.to_s(:human, precision: 4,
+ # significant: false) # => "1.2346 Million"
+ # 1234567.to_s(:human, precision: 1,
+ # separator: ',',
+ # significant: false) # => "1,2 Million"
def to_formatted_s(format = :default, options = {})
case format
when :phone
diff --git a/activesupport/lib/active_support/core_ext/numeric/time.rb b/activesupport/lib/active_support/core_ext/numeric/time.rb
index 2bf3d1f278..87b9a23aef 100644
--- a/activesupport/lib/active_support/core_ext/numeric/time.rb
+++ b/activesupport/lib/active_support/core_ext/numeric/time.rb
@@ -8,13 +8,13 @@ class Numeric
# These methods use Time#advance for precise date calculations when using from_now, ago, etc.
# as well as adding or subtracting their results from a Time object. For example:
#
- # # equivalent to Time.current.advance(:months => 1)
+ # # equivalent to Time.current.advance(months: 1)
# 1.month.from_now
#
- # # equivalent to Time.current.advance(:years => 2)
+ # # equivalent to Time.current.advance(years: 2)
# 2.years.from_now
#
- # # equivalent to Time.current.advance(:months => 4, :years => 5)
+ # # equivalent to Time.current.advance(months: 4, years: 5)
# (4.months + 5.years).from_now
#
# While these methods provide precise calculation when used as in the examples above, care
diff --git a/activesupport/lib/active_support/core_ext/object/blank.rb b/activesupport/lib/active_support/core_ext/object/blank.rb
index e238fef5a2..8a5eb4bc93 100644
--- a/activesupport/lib/active_support/core_ext/object/blank.rb
+++ b/activesupport/lib/active_support/core_ext/object/blank.rb
@@ -43,7 +43,6 @@ class NilClass
# +nil+ is blank:
#
# nil.blank? # => true
- #
def blank?
true
end
@@ -53,7 +52,6 @@ class FalseClass
# +false+ is blank:
#
# false.blank? # => true
- #
def blank?
true
end
@@ -63,7 +61,6 @@ class TrueClass
# +true+ is not blank:
#
# true.blank? # => false
- #
def blank?
false
end
@@ -74,7 +71,6 @@ class Array
#
# [].blank? # => true
# [1,2,3].blank? # => false
- #
alias_method :blank?, :empty?
end
@@ -82,8 +78,7 @@ class Hash
# A hash is blank if it's empty:
#
# {}.blank? # => true
- # {:key => 'value'}.blank? # => false
- #
+ # { key: 'value' }.blank? # => false
alias_method :blank?, :empty?
end
@@ -94,7 +89,6 @@ class String
# ' '.blank? # => true
# ' '.blank? # => true
# ' something here '.blank? # => false
- #
def blank?
self !~ /[^[:space:]]/
end
@@ -105,7 +99,6 @@ class Numeric #:nodoc:
#
# 1.blank? # => false
# 0.blank? # => false
- #
def blank?
false
end
diff --git a/activesupport/lib/active_support/core_ext/object/duplicable.rb b/activesupport/lib/active_support/core_ext/object/duplicable.rb
index f1b755c2c4..9cd7485e2e 100644
--- a/activesupport/lib/active_support/core_ext/object/duplicable.rb
+++ b/activesupport/lib/active_support/core_ext/object/duplicable.rb
@@ -31,7 +31,6 @@ class NilClass
#
# nil.duplicable? # => false
# nil.dup # => TypeError: can't dup NilClass
- #
def duplicable?
false
end
@@ -42,7 +41,6 @@ class FalseClass
#
# false.duplicable? # => false
# false.dup # => TypeError: can't dup FalseClass
- #
def duplicable?
false
end
@@ -53,7 +51,6 @@ class TrueClass
#
# true.duplicable? # => false
# true.dup # => TypeError: can't dup TrueClass
- #
def duplicable?
false
end
@@ -64,7 +61,6 @@ class Symbol
#
# :my_symbol.duplicable? # => false
# :my_symbol.dup # => TypeError: can't dup Symbol
- #
def duplicable?
false
end
@@ -75,7 +71,6 @@ class Numeric
#
# 3.duplicable? # => false
# 3.dup # => TypeError: can't dup Fixnum
- #
def duplicable?
false
end
diff --git a/activesupport/lib/active_support/core_ext/object/to_json.rb b/activesupport/lib/active_support/core_ext/object/to_json.rb
index e7dc60a612..83cc8066e7 100644
--- a/activesupport/lib/active_support/core_ext/object/to_json.rb
+++ b/activesupport/lib/active_support/core_ext/object/to_json.rb
@@ -17,3 +17,11 @@ end
end
end
end
+
+module Process
+ class Status
+ def as_json(options = nil)
+ { :exitstatus => exitstatus, :pid => pid }
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/object/with_options.rb b/activesupport/lib/active_support/core_ext/object/with_options.rb
index e058367111..42e388b065 100644
--- a/activesupport/lib/active_support/core_ext/object/with_options.rb
+++ b/activesupport/lib/active_support/core_ext/object/with_options.rb
@@ -10,16 +10,16 @@ class Object
# Without <tt>with_options></tt>, this code contains duplication:
#
# class Account < ActiveRecord::Base
- # has_many :customers, :dependent => :destroy
- # has_many :products, :dependent => :destroy
- # has_many :invoices, :dependent => :destroy
- # has_many :expenses, :dependent => :destroy
+ # has_many :customers, dependent: :destroy
+ # has_many :products, dependent: :destroy
+ # has_many :invoices, dependent: :destroy
+ # has_many :expenses, dependent: :destroy
# end
#
# Using <tt>with_options</tt>, we can remove the duplication:
#
# class Account < ActiveRecord::Base
- # with_options :dependent => :destroy do |assoc|
+ # with_options dependent: :destroy do |assoc|
# assoc.has_many :customers
# assoc.has_many :products
# assoc.has_many :invoices
@@ -29,14 +29,13 @@ class Object
#
# It can also be used with an explicit receiver:
#
- # I18n.with_options :locale => user.locale, :scope => 'newsletter' do |i18n|
+ # I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n|
# subject i18n.t :subject
- # body i18n.t :body, :user_name => user.name
+ # body i18n.t :body, user_name: user.name
# end
#
# <tt>with_options</tt> can also be nested since the call is forwarded to its receiver.
# Each nesting level will merge inherited defaults in addition to their own.
- #
def with_options(options)
yield ActiveSupport::OptionMerger.new(self, options)
end
diff --git a/activesupport/lib/active_support/core_ext/string/filters.rb b/activesupport/lib/active_support/core_ext/string/filters.rb
index 8644529806..e05447439a 100644
--- a/activesupport/lib/active_support/core_ext/string/filters.rb
+++ b/activesupport/lib/active_support/core_ext/string/filters.rb
@@ -24,16 +24,16 @@ class String
#
# Pass a string or regexp <tt>:separator</tt> to truncate +text+ at a natural break:
#
- # 'Once upon a time in a world far far away'.truncate(27, :separator => ' ')
+ # 'Once upon a time in a world far far away'.truncate(27, separator: ' ')
# # => "Once upon a time in a..."
#
- # 'Once upon a time in a world far far away'.truncate(27, :separator => /\s/)
+ # 'Once upon a time in a world far far away'.truncate(27, separator: /\s/)
# # => "Once upon a time in a..."
#
# The last characters will be replaced with the <tt>:omission</tt> string (defaults to "...")
# for a total length not exceeding <tt>length</tt>:
#
- # 'And they found that many people were sleeping better.'.truncate(25, :omission => '... (continued)')
+ # 'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
# # => "And they f... (continued)"
def truncate(truncate_at, options = {})
return dup unless length > truncate_at
diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb
index c17d695967..5f85cedcf5 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -3,7 +3,7 @@ require 'active_support/core_ext/kernel/singleton_class'
class ERB
module Util
- HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#x27;' }
+ HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#39;' }
JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+));)/
JSON_ESCAPE_REGEXP = /[&"><]/
@@ -59,19 +59,11 @@ class ERB
#
# json_escape('{"name":"john","created_at":"2010-04-28T01:39:31Z","id":1}')
# # => {name:john,created_at:2010-04-28T01:39:31Z,id:1}
- #
- # This method is also aliased as +j+, and available as a helper
- # in Rails templates:
- #
- # <%=j @person.to_json %>
- #
def json_escape(s)
result = s.to_s.gsub(JSON_ESCAPE_REGEXP) { |special| JSON_ESCAPE[special] }
s.html_safe? ? result.html_safe : result
end
- alias j json_escape
- module_function :j
module_function :json_escape
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 d0f574f2ba..e3665cd896 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -2,18 +2,12 @@ require 'active_support/duration'
require 'active_support/core_ext/time/conversions'
require 'active_support/time_with_zone'
require 'active_support/core_ext/time/zones'
+require 'active_support/core_ext/date_and_time/calculations'
class Time
+ include DateAndTime::Calculations
+
COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
- DAYS_INTO_WEEK = {
- :monday => 0,
- :tuesday => 1,
- :wednesday => 2,
- :thursday => 3,
- :friday => 4,
- :saturday => 5,
- :sunday => 6
- }
class << self
# Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances
@@ -63,29 +57,22 @@ class Time
end
end
- # Tells whether the Time object's time lies in the past
- def past?
- self < ::Time.current
- end
-
- # Tells whether the Time object's time is today
- def today?
- to_date == ::Date.current
- end
-
- # Tells whether the Time object's time lies in the future
- def future?
- self > ::Time.current
- end
-
# Seconds since midnight: Time.now.seconds_since_midnight
def seconds_since_midnight
to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
end
- # Returns a new Time where one or more of the elements have been changed according to the +options+ parameter. The time options
- # (hour, min, sec, usec) reset cascadingly, so if only the hour is passed, then minute, sec, and usec is set to 0. If the hour and
- # minute is passed, then sec and usec is set to 0.
+ # 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,
+ # then minute, sec, and usec is set to 0. If the hour and minute is passed, then
+ # sec and usec is set to 0. The +options+ parameter takes a hash with any of these
+ # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>,
+ # <tt>:sec</tt>, <tt>:usec</tt>.
+ #
+ # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
+ # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
+ # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
def change(options)
new_year = options.fetch(:year, year)
new_month = options.fetch(:month, month)
@@ -146,116 +133,6 @@ class Time
end
alias :in :since
- # Returns a new Time representing the time a number of specified weeks ago.
- def weeks_ago(weeks)
- advance(:weeks => -weeks)
- end
-
- # Returns a new Time representing the time a number of specified months ago
- def months_ago(months)
- advance(:months => -months)
- end
-
- # Returns a new Time representing the time a number of specified months in the future
- def months_since(months)
- advance(:months => months)
- end
-
- # Returns a new Time representing the time a number of specified years ago
- def years_ago(years)
- advance(:years => -years)
- end
-
- # Returns a new Time representing the time a number of specified years in the future
- def years_since(years)
- advance(:years => years)
- end
-
- # Short-hand for years_ago(1)
- def prev_year
- years_ago(1)
- end
- alias_method :last_year, :prev_year
-
- # Short-hand for years_since(1)
- def next_year
- years_since(1)
- end
-
- # Short-hand for months_ago(1)
- def prev_month
- months_ago(1)
- end
- alias_method :last_month, :prev_month
-
- # Short-hand for months_since(1)
- def next_month
- months_since(1)
- end
-
- # Short-hand for months_ago(3)
- def prev_quarter
- months_ago(3)
- end
- alias_method :last_quarter, :prev_quarter
-
- # Short-hand for months_since(3)
- def next_quarter
- months_since(3)
- end
-
- # Returns number of days to start of this week, week starts on start_day (default is :monday).
- def days_to_week_start(start_day = :monday)
- start_day_number = DAYS_INTO_WEEK[start_day]
- current_day_number = wday != 0 ? wday - 1 : 6
- days_span = current_day_number - start_day_number
-
- days_span >= 0 ? days_span : 7 + days_span
- end
-
- # Returns a new Time representing the "start" of this week, week starts on start_day (default is :monday, i.e. Monday, 0:00).
- def beginning_of_week(start_day = :monday)
- days_to_start = days_to_week_start(start_day)
- (self - days_to_start.days).midnight
- end
- alias :at_beginning_of_week :beginning_of_week
-
- # Returns a new +Date+/+DateTime+ representing the start of this week. Week is
- # assumed to start on a Monday. +DateTime+ objects have their time set to 0:00.
- def monday
- beginning_of_week
- end
-
- # Returns a new Time representing the end of this week, week starts on start_day (default is :monday, i.e. end of Sunday).
- def end_of_week(start_day = :monday)
- days_to_end = 6 - days_to_week_start(start_day)
- (self + days_to_end.days).end_of_day
- end
- alias :at_end_of_week :end_of_week
-
- # Returns a new +Date+/+DateTime+ representing the end of this week. Week is
- # assumed to start on a Monday. +DateTime+ objects have their time set to 23:59:59.
- def sunday
- end_of_week
- end
-
- # Returns a new Time representing the start of the given day in the previous week (default is :monday).
- def prev_week(day = :monday)
- ago(1.week).
- beginning_of_week.
- since(DAYS_INTO_WEEK[day].day).
- change(:hour => 0)
- end
- alias_method :last_week, :prev_week
-
- # Returns a new Time representing the start of the given day in next week (default is :monday).
- def next_week(day = :monday)
- since(1.week).
- beginning_of_week.
- since(DAYS_INTO_WEEK[day].day).
- change(:hour => 0)
- end
-
# Returns a new Time representing the start of the day (0:00)
def beginning_of_day
#(self - seconds_since_midnight).change(:usec => 0)
@@ -290,77 +167,14 @@ class Time
)
end
- # Returns a new Time representing the start of the month (1st of the month, 0:00)
- def beginning_of_month
- #self - ((self.mday-1).days + self.seconds_since_midnight)
- change(:day => 1, :hour => 0)
- end
- alias :at_beginning_of_month :beginning_of_month
-
- # Returns a new Time representing the end of the month (end of the last day of the month)
- def end_of_month
- #self - ((self.mday-1).days + self.seconds_since_midnight)
- last_day = ::Time.days_in_month(month, year)
- change(
- :day => last_day,
- :hour => 23,
- :min => 59,
- :sec => 59,
- :usec => Rational(999999999, 1000)
- )
- end
- alias :at_end_of_month :end_of_month
-
- # Returns a new Time representing the start of the quarter (1st of january, april, july, october, 0:00)
- def beginning_of_quarter
- first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month }
- beginning_of_month.change(:month => first_quarter_month)
- end
- alias :at_beginning_of_quarter :beginning_of_quarter
-
- # Returns a new Time representing the end of the quarter (end of the last day of march, june, september, december)
- def end_of_quarter
- last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month }
- beginning_of_month.change(:month => last_quarter_month).end_of_month
- end
- alias :at_end_of_quarter :end_of_quarter
-
- # Returns a new Time representing the start of the year (1st of january, 0:00)
- def beginning_of_year
- change(:month => 1, :day => 1, :hour => 0)
- end
- alias :at_beginning_of_year :beginning_of_year
-
- # Returns a new Time representing the end of the year (end of the 31st of december)
- def end_of_year
- change(
- :month => 12,
- :day => 31,
- :hour => 23,
- :min => 59,
- :sec => 59,
- :usec => Rational(999999999, 1000)
- )
- end
- alias :at_end_of_year :end_of_year
-
- # Convenience method which returns a new Time representing the time 1 day ago
- def yesterday
- advance(:days => -1)
- end
-
- # Convenience method which returns a new Time representing the time 1 day since the instance time
- def tomorrow
- advance(:days => 1)
- end
-
# Returns a Range representing the whole day of the current time.
def all_day
beginning_of_day..end_of_day
end
- # Returns a Range representing the whole week of the current time. Week starts on start_day (default is :monday, i.e. end of Sunday).
- def all_week(start_day = :monday)
+ # Returns a Range representing the whole week of the current time.
+ # Week starts on start_day, default is <tt>Date.week_start</tt> or <tt>config.week_start</tt> when set.
+ def all_week(start_day = Date.beginning_of_week)
beginning_of_week(start_day)..end_of_week(start_day)
end
diff --git a/activesupport/lib/active_support/core_ext/time/conversions.rb b/activesupport/lib/active_support/core_ext/time/conversions.rb
index 10ca26acf2..48654eb1cc 100644
--- a/activesupport/lib/active_support/core_ext/time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/time/conversions.rb
@@ -23,17 +23,17 @@ class Time
#
# This method is aliased to <tt>to_s</tt>.
#
- # time = Time.now # => Thu Jan 18 06:10:17 CST 2007
+ # time = Time.now # => Thu Jan 18 06:10:17 CST 2007
#
- # time.to_formatted_s(:time) # => "06:10"
- # time.to_s(:time) # => "06:10"
+ # time.to_formatted_s(:time) # => "06:10"
+ # time.to_s(:time) # => "06:10"
#
- # 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"
- # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
+ # 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"
+ # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
#
# == Adding your own time formats to +to_formatted_s+
# You can add your own formats to the Time::DATE_FORMATS hash.
@@ -42,7 +42,7 @@ class Time
#
# # config/initializers/time_formats.rb
# Time::DATE_FORMATS[:month_and_year] = '%B %Y'
- # Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
+ # Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
def to_formatted_s(format = :default)
if formatter = DATE_FORMATS[format]
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
@@ -55,8 +55,8 @@ class Time
# Returns the UTC offset as an +HH:MM formatted string.
#
- # Time.local(2000).formatted_offset # => "-06:00"
- # Time.local(2000).formatted_offset(false) # => "-0600"
+ # Time.local(2000).formatted_offset # => "-06:00"
+ # Time.local(2000).formatted_offset(false) # => "-0600"
def formatted_offset(colon = true, alternate_utc_string = nil)
utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
end
diff --git a/activesupport/lib/active_support/core_ext/time/zones.rb b/activesupport/lib/active_support/core_ext/time/zones.rb
index 37bc3fae24..139d48f59c 100644
--- a/activesupport/lib/active_support/core_ext/time/zones.rb
+++ b/activesupport/lib/active_support/core_ext/time/zones.rb
@@ -76,8 +76,8 @@ class Time
# Returns the simultaneous time in <tt>Time.zone</tt>.
#
- # Time.zone = 'Hawaii' # => 'Hawaii'
- # Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+ # Time.zone = 'Hawaii' # => 'Hawaii'
+ # Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
#
# This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
# instead of the operating system's time zone.
@@ -85,7 +85,7 @@ class Time
# You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
# and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
#
- # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
+ # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
def in_time_zone(zone = ::Time.zone)
if zone
ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone))
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index 77cab6f08d..42746582fa 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -43,8 +43,9 @@ module ActiveSupport #:nodoc:
mattr_accessor :autoload_once_paths
self.autoload_once_paths = []
- # An array of qualified constant names that have been loaded. Adding a name to
- # this array will cause it to be unloaded the next time Dependencies are cleared.
+ # An array of qualified constant names that have been loaded. Adding a name
+ # to this array will cause it to be unloaded the next time Dependencies are
+ # cleared.
mattr_accessor :autoloaded_constants
self.autoloaded_constants = []
@@ -53,30 +54,32 @@ module ActiveSupport #:nodoc:
mattr_accessor :explicitly_unloadable_constants
self.explicitly_unloadable_constants = []
- # The logger is used for generating information on the action run-time (including benchmarking) if available.
- # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
+ # The logger is used for generating information on the action run-time
+ # (including benchmarking) if available. Can be set to nil for no logging.
+ # Compatible with both Ruby's own Logger and Log4r loggers.
mattr_accessor :logger
- # Set to true to enable logging of const_missing and file loads
+ # Set to +true+ to enable logging of const_missing and file loads.
mattr_accessor :log_activity
self.log_activity = false
- # The WatchStack keeps a stack of the modules being watched as files are loaded.
- # If a file in the process of being loaded (parent.rb) triggers the load of
- # another file (child.rb) the stack will ensure that child.rb handles the new
- # constants.
+ # The WatchStack keeps a stack of the modules being watched as files are
+ # loaded. If a file in the process of being loaded (parent.rb) triggers the
+ # load of another file (child.rb) the stack will ensure that child.rb
+ # handles the new constants.
#
# If child.rb is being autoloaded, its constants will be added to
# autoloaded_constants. If it was being `require`d, they will be discarded.
#
# This is handled by walking back up the watch stack and adding the constants
- # found by child.rb to the list of original constants in parent.rb
+ # found by child.rb to the list of original constants in parent.rb.
class WatchStack
include Enumerable
# @watching is a stack of lists of constants being watched. For instance,
- # if parent.rb is autoloaded, the stack will look like [[Object]]. If parent.rb
- # then requires namespace/child.rb, the stack will look like [[Object], [Namespace]].
+ # if parent.rb is autoloaded, the stack will look like [[Object]]. If
+ # parent.rb then requires namespace/child.rb, the stack will look like
+ # [[Object], [Namespace]].
def initialize
@watching = []
@@ -91,7 +94,8 @@ module ActiveSupport #:nodoc:
!@watching.empty?
end
- # return a list of new constants found since the last call to watch_namespaces
+ # Returns a list of new constants found since the last call to
+ # <tt>watch_namespaces</tt>.
def new_constants
constants = []
@@ -127,7 +131,8 @@ module ActiveSupport #:nodoc:
pop_modules(@watching.pop)
end
- # Add a set of modules to the watch stack, remembering the initial constants
+ # Add a set of modules to the watch stack, remembering the initial
+ # constants.
def watch_namespaces(namespaces)
@watching << namespaces.map do |namespace|
module_name = Dependencies.to_constant_name(namespace)
@@ -149,7 +154,7 @@ module ActiveSupport #:nodoc:
mattr_accessor :constant_watch_stack
self.constant_watch_stack = WatchStack.new
- # Module includes this module
+ # Module includes this module.
module ModuleConstMissing #:nodoc:
def self.append_features(base)
base.class_eval do
@@ -169,47 +174,12 @@ module ActiveSupport #:nodoc:
end
def const_missing(const_name)
- klass_name = name.presence || "Object"
-
- # Since Ruby does not pass the nesting at the point the unknown
- # constant triggered the callback we cannot fully emulate constant
- # name lookup and need to make a trade-off: we are going to assume
- # that the nesting in the body of Foo::Bar is [Foo::Bar, Foo] even
- # though it might not be. Counterexamples are
- #
- # class Foo::Bar
- # Module.nesting # => [Foo::Bar]
- # end
- #
- # or
- #
- # module M::N
- # module S::T
- # Module.nesting # => [S::T, M::N]
- # end
- # end
- #
- # for example.
- nesting = []
- klass_name.to_s.scan(/::|$/) { nesting.unshift $` }
-
- # If there are multiple levels of nesting to search under, the top
- # level is the one we want to report as the lookup fail.
- error = nil
-
- nesting.each do |namespace|
- begin
- return Dependencies.load_missing_constant Inflector.constantize(namespace), const_name
- rescue NoMethodError then raise
- rescue NameError => e
- error ||= e
- end
- end
-
- # Raise the first error for this set. If this const_missing came from an
- # earlier const_missing, this will result in the real error bubbling
- # all the way up
- raise error
+ # The interpreter does not pass nesting information, and in the
+ # case of anonymous modules we cannot even make the trade-off of
+ # assuming their name reflects the nesting. Resort to Object as
+ # the only meaningful guess we can make.
+ from_mod = anonymous? ? ::Object : self
+ Dependencies.load_missing_constant(from_mod, const_name)
end
def unloadable(const_desc = self)
@@ -217,7 +187,7 @@ module ActiveSupport #:nodoc:
end
end
- # Object includes this module
+ # Object includes this module.
module Loadable #:nodoc:
def self.exclude_from(base)
base.class_eval { define_method(:load, Kernel.instance_method(:load)) }
@@ -258,25 +228,25 @@ module ActiveSupport #:nodoc:
result
end
- # Mark the given constant as unloadable. Unloadable constants are removed each
- # time dependencies are cleared.
+ # Mark the given constant as unloadable. Unloadable constants are removed
+ # each time dependencies are cleared.
#
# Note that marking a constant for unloading need only be done once. Setup
# or init scripts may list each unloadable constant that may need unloading;
- # each constant will be removed for every subsequent clear, as opposed to for
- # the first clear.
+ # each constant will be removed for every subsequent clear, as opposed to
+ # for the first clear.
#
# The provided constant descriptor may be a (non-anonymous) module or class,
# or a qualified constant name as a string or symbol.
#
- # Returns true if the constant was not previously marked for unloading, false
- # otherwise.
+ # Returns +true+ if the constant was not previously marked for unloading,
+ # +false+ otherwise.
def unloadable(const_desc)
Dependencies.mark_for_unload const_desc
end
end
- # Exception file-blaming
+ # Exception file-blaming.
module Blamable #:nodoc:
def blame_file!(file)
(@blamed_files ||= []).unshift file
@@ -331,7 +301,7 @@ module ActiveSupport #:nodoc:
def require_or_load(file_name, const_path = nil)
log_call file_name, const_path
- file_name = $1 if file_name =~ /^(.*)\.rb$/
+ file_name = $` if file_name =~ /\.rb\z/
expanded = File.expand_path(file_name)
return if loaded.include?(expanded)
@@ -372,10 +342,11 @@ module ActiveSupport #:nodoc:
Object.qualified_const_defined?(path.sub(/^::/, ''), false)
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.
+ # 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 = autoload_paths)
- path = $1 if path =~ /\A(.*)\.rb\Z/
+ path = $` if path =~ /\.rb\z/
expanded_path = File.expand_path(path)
paths = []
@@ -406,7 +377,8 @@ module ActiveSupport #:nodoc:
end
# Does the provided path_suffix correspond to an autoloadable module?
- # Instead of returning a boolean, the autoload base for this module is returned.
+ # Instead of returning a boolean, the autoload base for this module is
+ # returned.
def autoloadable_module?(path_suffix)
autoload_paths.each do |load_path|
return load_path if File.directory? File.join(load_path, path_suffix)
@@ -420,10 +392,10 @@ module ActiveSupport #:nodoc:
end
# Attempt to autoload the provided module name by searching for a directory
- # matching the expected path suffix. If found, the module is created and assigned
- # to +into+'s constants with the name +const_name+. Provided that the directory
- # was loaded from a reloadable base path, it is added to the set of constants
- # that are to be unloaded.
+ # matching the expected path suffix. If found, the module is created and
+ # assigned to +into+'s constants with the name +const_name+. Provided that
+ # the directory was loaded from a reloadable base path, it is added to the
+ # set of constants that are to be unloaded.
def autoload_module!(into, const_name, qualified_name, path_suffix)
return nil unless base_path = autoloadable_module?(path_suffix)
mod = Module.new
@@ -437,13 +409,13 @@ module ActiveSupport #:nodoc:
# addition of these constants. Each that is defined will be marked as
# autoloaded, and will be removed when Dependencies.clear is next called.
#
- # If the second parameter is left off, then Dependencies will construct a set
- # of names that the file at +path+ may define. See
+ # If the second parameter is left off, then Dependencies will construct a
+ # set of names that the file at +path+ may define. See
# +loadable_constants_for_path+ for more details.
def load_file(path, const_paths = loadable_constants_for_path(path))
log_call path, const_paths
const_paths = [const_paths].compact unless const_paths.is_a? Array
- parent_paths = const_paths.collect { |const_path| /(.*)::[^:]+\Z/ =~ const_path ? $1 : :Object }
+ parent_paths = const_paths.collect { |const_path| const_path[/.*(?=::)/] || :Object }
result = nil
newly_defined_paths = new_constants_in(*parent_paths) do
@@ -456,15 +428,15 @@ module ActiveSupport #:nodoc:
result
end
- # Return the constant path for the provided parent and constant name.
+ # Returns the constant path for the provided parent and constant name.
def qualified_name_for(mod, name)
mod_name = to_constant_name mod
mod_name == "Object" ? name.to_s : "#{mod_name}::#{name}"
end
# Load the constant named +const_name+ which is missing from +from_mod+. If
- # it is not possible to load the constant into from_mod, try its parent module
- # using const_missing.
+ # it is not possible to load the constant into from_mod, try its parent
+ # module using +const_missing+.
def load_missing_constant(from_mod, const_name)
log_call from_mod, const_name
@@ -479,10 +451,17 @@ module ActiveSupport #: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, false)
- return from_mod.const_get(const_name)
+ if file_path
+ expanded = File.expand_path(file_path)
+ expanded.sub!(/\.rb\z/, '')
+
+ if loaded.include?(expanded)
+ raise "Circular dependency detected while autoloading constant #{qualified_name}"
+ else
+ require_or_load(expanded)
+ raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{file_path} to define it" unless from_mod.const_defined?(const_name, false)
+ return from_mod.const_get(const_name)
+ end
elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
return mod
elsif (parent = from_mod.parent) && parent != from_mod &&
@@ -492,6 +471,25 @@ module ActiveSupport #:nodoc:
# const_missing must be due to from_mod::const_name, which should not
# return constants from from_mod's parents.
begin
+ # Since Ruby does not pass the nesting at the point the unknown
+ # constant triggered the callback we cannot fully emulate constant
+ # name lookup and need to make a trade-off: we are going to assume
+ # that the nesting in the body of Foo::Bar is [Foo::Bar, Foo] even
+ # though it might not be. Counterexamples are
+ #
+ # class Foo::Bar
+ # Module.nesting # => [Foo::Bar]
+ # end
+ #
+ # or
+ #
+ # module M::N
+ # module S::T
+ # Module.nesting # => [S::T, M::N]
+ # end
+ # end
+ #
+ # for example.
return parent.const_missing(const_name)
rescue NameError => e
raise unless e.missing_name? qualified_name_for(parent, const_name)
@@ -567,7 +565,7 @@ module ActiveSupport #:nodoc:
end
# Get the reference for class named +name+ if one exists.
- # Otherwise returns nil.
+ # Otherwise returns +nil+.
def safe_constantize(name)
Reference.safe_get(name)
end
diff --git a/activesupport/lib/active_support/dependencies/autoload.rb b/activesupport/lib/active_support/dependencies/autoload.rb
index 4045db3232..9fc58a338f 100644
--- a/activesupport/lib/active_support/dependencies/autoload.rb
+++ b/activesupport/lib/active_support/dependencies/autoload.rb
@@ -1,52 +1,77 @@
require "active_support/inflector/methods"
module ActiveSupport
+ # Autoload and eager load conveniences for your library.
+ #
+ # This module allows you to define autoloads based on
+ # Rails conventions (i.e. no need to define the path
+ # it is automatically guessed based on the filename)
+ # and also define a set of constants that needs to be
+ # eager loaded:
+ #
+ # module MyLib
+ # extend ActiveSupport::Autoload
+ #
+ # autoload :Model
+ #
+ # eager_autoload do
+ # autoload :Cache
+ # end
+ # end
+ #
+ # Then your library can be eager loaded by simply calling:
+ #
+ # MyLib.eager_load!
module Autoload
- @@autoloads = {}
- @@under_path = nil
- @@at_path = nil
- @@eager_autoload = false
+ def self.extended(base) # :nodoc:
+ base.class_eval do
+ @_autoloads = {}
+ @_under_path = nil
+ @_at_path = nil
+ @_eager_autoload = false
+ end
+ end
- def autoload(const_name, path = @@at_path)
+ def autoload(const_name, path = @_at_path)
unless path
- full = [name, @@under_path, const_name.to_s, path].compact.join("::")
+ full = [name, @_under_path, const_name.to_s, path].compact.join("::")
path = Inflector.underscore(full)
end
- if @@eager_autoload
- @@autoloads[const_name] = path
+ if @_eager_autoload
+ @_autoloads[const_name] = path
end
super const_name, path
end
def autoload_under(path)
- @@under_path, old_path = path, @@under_path
+ @_under_path, old_path = path, @_under_path
yield
ensure
- @@under_path = old_path
+ @_under_path = old_path
end
def autoload_at(path)
- @@at_path, old_path = path, @@at_path
+ @_at_path, old_path = path, @_at_path
yield
ensure
- @@at_path = old_path
+ @_at_path = old_path
end
def eager_autoload
- old_eager, @@eager_autoload = @@eager_autoload, true
+ old_eager, @_eager_autoload = @_eager_autoload, true
yield
ensure
- @@eager_autoload = old_eager
+ @_eager_autoload = old_eager
end
- def self.eager_autoload!
- @@autoloads.values.each { |file| require file }
+ def eager_load!
+ @_autoloads.values.each { |file| require file }
end
def autoloads
- @@autoloads
+ @_autoloads
end
end
end
diff --git a/activesupport/lib/active_support/deprecation.rb b/activesupport/lib/active_support/deprecation.rb
index e3b4a7240e..b3f5fde335 100644
--- a/activesupport/lib/active_support/deprecation.rb
+++ b/activesupport/lib/active_support/deprecation.rb
@@ -1,19 +1,34 @@
require 'active_support/core_ext/module/deprecation'
+require 'active_support/deprecation/instance_delegator'
require 'active_support/deprecation/behaviors'
require 'active_support/deprecation/reporting'
require 'active_support/deprecation/method_wrappers'
require 'active_support/deprecation/proxy_wrappers'
+require 'singleton'
module ActiveSupport
- module Deprecation
- class << self
- # The version the deprecated behavior will be removed, by default.
- attr_accessor :deprecation_horizon
- end
- self.deprecation_horizon = '4.1'
+ # \Deprecation specifies the API used by Rails to deprecate methods, instance
+ # variables, objects and constants.
+ class Deprecation
+ include Singleton
+ include InstanceDelegator
+ include Behavior
+ include Reporting
+ include MethodWrapper
+
+ # The version the deprecated behavior will be removed, by default.
+ attr_accessor :deprecation_horizon
- # By default, warnings are not silenced and debugging is off.
- self.silenced = false
- self.debug = false
+ # It accepts two parameters on initialization. The first is an version of library
+ # and the second is an library name
+ #
+ # ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
+ def initialize(deprecation_horizon = '4.1', gem_name = 'Rails')
+ self.gem_name = gem_name
+ self.deprecation_horizon = deprecation_horizon
+ # By default, warnings are not silenced and debugging is off.
+ self.silenced = false
+ self.debug = false
+ end
end
-end \ No newline at end of file
+end
diff --git a/activesupport/lib/active_support/deprecation/behaviors.rb b/activesupport/lib/active_support/deprecation/behaviors.rb
index fc962dcb57..90db180124 100644
--- a/activesupport/lib/active_support/deprecation/behaviors.rb
+++ b/activesupport/lib/active_support/deprecation/behaviors.rb
@@ -1,63 +1,63 @@
require "active_support/notifications"
module ActiveSupport
- module Deprecation
- class << self
+ class Deprecation
+ # Default warning behaviors per Rails.env.
+ DEFAULT_BEHAVIORS = {
+ :stderr => Proc.new { |message, callstack|
+ $stderr.puts(message)
+ $stderr.puts callstack.join("\n ") if debug
+ },
+ :log => Proc.new { |message, callstack|
+ logger =
+ if defined?(Rails) && Rails.logger
+ Rails.logger
+ else
+ require 'active_support/logger'
+ ActiveSupport::Logger.new($stderr)
+ end
+ logger.warn message
+ logger.debug callstack.join("\n ") if debug
+ },
+ :notify => Proc.new { |message, callstack|
+ ActiveSupport::Notifications.instrument("deprecation.rails",
+ :message => message, :callstack => callstack)
+ },
+ :silence => Proc.new { |message, callstack| }
+ }
+
+ module Behavior
# Whether to print a backtrace along with the warning.
attr_accessor :debug
- # Returns the current behavior or if one isn't set, defaults to +:stderr+
+ # Returns the current behavior or if one isn't set, defaults to +:stderr+.
def behavior
@behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
end
- # Sets the behavior to the specified value. Can be a single value, array, or
- # an object that responds to +call+.
+ # Sets the behavior to the specified value. Can be a single value, array,
+ # or an object that responds to +call+.
#
# Available behaviors:
#
- # [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
+ # [+stderr+] Log all deprecation warnings to +$stderr+.
# [+log+] Log all deprecation warnings to +Rails.logger+.
- # [+notify+] Use <tt>ActiveSupport::Notifications</tt> to notify +deprecation.rails+.
+ # [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
# [+silence+] Do nothing.
#
# Setting behaviors only affects deprecations that happen after boot time.
- # Deprecation warnings raised by gems are not affected by this setting because
- # they happen before Rails boots up.
+ # Deprecation warnings raised by gems are not affected by this setting
+ # because they happen before Rails boots up.
#
# ActiveSupport::Deprecation.behavior = :stderr
# ActiveSupport::Deprecation.behavior = [:stderr, :log]
# ActiveSupport::Deprecation.behavior = MyCustomHandler
- # ActiveSupport::Deprecation.behavior = proc { |message, callstack|
+ # ActiveSupport::Deprecation.behavior = proc { |message, callstack|
# # custom stuff
# }
def behavior=(behavior)
@behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
end
end
-
- # Default warning behaviors per Rails.env.
- DEFAULT_BEHAVIORS = {
- :stderr => Proc.new { |message, callstack|
- $stderr.puts(message)
- $stderr.puts callstack.join("\n ") if debug
- },
- :log => Proc.new { |message, callstack|
- logger =
- if defined?(Rails) && Rails.logger
- Rails.logger
- else
- require 'active_support/logger'
- ActiveSupport::Logger.new($stderr)
- end
- logger.warn message
- logger.debug callstack.join("\n ") if debug
- },
- :notify => Proc.new { |message, callstack|
- ActiveSupport::Notifications.instrument("deprecation.rails",
- :message => message, :callstack => callstack)
- },
- :silence => Proc.new { |message, callstack| }
- }
end
end
diff --git a/activesupport/lib/active_support/deprecation/instance_delegator.rb b/activesupport/lib/active_support/deprecation/instance_delegator.rb
new file mode 100644
index 0000000000..ff240cb887
--- /dev/null
+++ b/activesupport/lib/active_support/deprecation/instance_delegator.rb
@@ -0,0 +1,24 @@
+require 'active_support/core_ext/kernel/singleton_class'
+require 'active_support/core_ext/module/delegation'
+
+module ActiveSupport
+ class Deprecation
+ module InstanceDelegator
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.public_class_method :new
+ end
+
+ module ClassMethods
+ def include(included_module)
+ included_module.instance_methods.each { |m| method_added(m) }
+ super
+ end
+
+ def method_added(method_name)
+ singleton_class.delegate(method_name, to: :instance)
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/deprecation/method_wrappers.rb b/activesupport/lib/active_support/deprecation/method_wrappers.rb
index 257b70e34a..d3907b03e5 100644
--- a/activesupport/lib/active_support/deprecation/method_wrappers.rb
+++ b/activesupport/lib/active_support/deprecation/method_wrappers.rb
@@ -2,45 +2,41 @@ require 'active_support/core_ext/module/aliasing'
require 'active_support/core_ext/array/extract_options'
module ActiveSupport
- module Deprecation
- # Declare that a method has been deprecated.
- #
- # module Fred
- # extend self
- #
- # def foo; end
- # def bar; end
- # def baz; end
- # end
- #
- # ActiveSupport::Deprecation.deprecate_methods(Fred, :foo, bar: :qux, baz: 'use Bar#baz instead')
- # # => [:foo, :bar, :baz]
- #
- # Fred.foo
- # # => "DEPRECATION WARNING: foo is deprecated and will be removed from Rails 4.1."
- #
- # Fred.bar
- # # => "DEPRECATION WARNING: bar is deprecated and will be removed from Rails 4.1 (use qux instead)."
- #
- # Fred.baz
- # # => "DEPRECATION WARNING: baz is deprecated and will be removed from Rails 4.1 (use Bar#baz instead)."
- def self.deprecate_methods(target_module, *method_names)
- options = method_names.extract_options!
- method_names += options.keys
+ class Deprecation
+ module MethodWrapper
+ # Declare that a method has been deprecated.
+ #
+ # module Fred
+ # extend self
+ #
+ # def foo; end
+ # def bar; end
+ # def baz; end
+ # end
+ #
+ # ActiveSupport::Deprecation.deprecate_methods(Fred, :foo, bar: :qux, baz: 'use Bar#baz instead')
+ # # => [:foo, :bar, :baz]
+ #
+ # Fred.foo
+ # # => "DEPRECATION WARNING: foo is deprecated and will be removed from Rails 4.1."
+ #
+ # Fred.bar
+ # # => "DEPRECATION WARNING: bar is deprecated and will be removed from Rails 4.1 (use qux instead)."
+ #
+ # Fred.baz
+ # # => "DEPRECATION WARNING: baz is deprecated and will be removed from Rails 4.1 (use Bar#baz instead)."
+ def deprecate_methods(target_module, *method_names)
+ options = method_names.extract_options!
+ deprecator = options.delete(:deprecator) || ActiveSupport::Deprecation.instance
+ method_names += options.keys
- method_names.each do |method_name|
- target_module.alias_method_chain(method_name, :deprecation) do |target, punctuation|
- target_module.module_eval(<<-end_eval, __FILE__, __LINE__ + 1)
- def #{target}_with_deprecation#{punctuation}(*args, &block)
- ::ActiveSupport::Deprecation.warn(
- ::ActiveSupport::Deprecation.deprecated_method_warning(
- :#{method_name},
- #{options[method_name].inspect}),
- caller
- )
- send(:#{target}_without_deprecation#{punctuation}, *args, &block)
+ method_names.each do |method_name|
+ target_module.alias_method_chain(method_name, :deprecation) do |target, punctuation|
+ target_module.send(:define_method, "#{target}_with_deprecation#{punctuation}") do |*args, &block|
+ deprecator.deprecation_warning(method_name, options[method_name], caller)
+ send(:"#{target}_without_deprecation#{punctuation}", *args, &block)
end
- end_eval
+ end
end
end
end
diff --git a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
index a65fcafb44..17e69c34a5 100644
--- a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
+++ b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
@@ -1,7 +1,7 @@
require 'active_support/inflector/methods'
module ActiveSupport
- module Deprecation
+ class Deprecation
class DeprecationProxy #:nodoc:
def self.new(*args, &block)
object = args.first
@@ -25,10 +25,20 @@ module ActiveSupport
end
end
- class DeprecatedObjectProxy < DeprecationProxy #:nodoc:
- def initialize(object, message)
+ # This DeprecatedObjectProxy transforms object to depracated object.
+ #
+ # @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!")
+ # @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!", deprecator_instance)
+ #
+ # When someone execute any method expect +inspect+ on proxy object this will
+ # trigger +warn+ method on +deprecator_instance+.
+ #
+ # Default deprecator is <tt>ActiveSupport::Deprecation</tt>
+ class DeprecatedObjectProxy < DeprecationProxy
+ def initialize(object, message, deprecator = ActiveSupport::Deprecation.instance)
@object = object
@message = message
+ @deprecator = deprecator
end
private
@@ -37,15 +47,40 @@ module ActiveSupport
end
def warn(callstack, called, args)
- ActiveSupport::Deprecation.warn(@message, callstack)
+ @deprecator.warn(@message, callstack)
end
end
- # Stand-in for <tt>@request</tt>, <tt>@attributes</tt>, <tt>@params</tt>, etc.
- # which emits deprecation warnings on any method call (except +inspect+).
- class DeprecatedInstanceVariableProxy < DeprecationProxy #:nodoc:
- def initialize(instance, method, var = "@#{method}")
- @instance, @method, @var = instance, method, var
+ # This DeprecatedInstanceVariableProxy transforms instance variable to
+ # depracated instance variable.
+ #
+ # class Example
+ # def initialize(deprecator)
+ # @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator)
+ # @_request = :a_request
+ # end
+ #
+ # def request
+ # @_request
+ # end
+ #
+ # def old_request
+ # @request
+ # end
+ # end
+ #
+ # When someone execute any method on @request variable this will trigger
+ # +warn+ method on +deprecator_instance+ and will fetch <tt>@_request</tt>
+ # variable via +request+ method and execute the same method on non-proxy
+ # instance variable.
+ #
+ # Default deprecator is <tt>ActiveSupport::Deprecation</tt>.
+ class DeprecatedInstanceVariableProxy < DeprecationProxy
+ def initialize(instance, method, var = "@#{method}", deprecator = ActiveSupport::Deprecation.instance)
+ @instance = instance
+ @method = method
+ @var = var
+ @deprecator = deprecator
end
private
@@ -54,14 +89,24 @@ module ActiveSupport
end
def warn(callstack, called, args)
- ActiveSupport::Deprecation.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack)
+ @deprecator.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack)
end
end
- class DeprecatedConstantProxy < DeprecationProxy #:nodoc:all
- def initialize(old_const, new_const)
+ # This DeprecatedConstantProxy transforms constant to depracated constant.
+ #
+ # OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST')
+ # OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST', deprecator_instance)
+ #
+ # When someone use old constant this will trigger +warn+ method on
+ # +deprecator_instance+.
+ #
+ # Default deprecator is <tt>ActiveSupport::Deprecation</tt>.
+ class DeprecatedConstantProxy < DeprecationProxy
+ def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance)
@old_const = old_const
@new_const = new_const
+ @deprecator = deprecator
end
def class
@@ -74,7 +119,7 @@ module ActiveSupport
end
def warn(callstack, called, args)
- ActiveSupport::Deprecation.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack)
+ @deprecator.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack)
end
end
end
diff --git a/activesupport/lib/active_support/deprecation/reporting.rb b/activesupport/lib/active_support/deprecation/reporting.rb
index a1e9618084..1ce54d9381 100644
--- a/activesupport/lib/active_support/deprecation/reporting.rb
+++ b/activesupport/lib/active_support/deprecation/reporting.rb
@@ -1,12 +1,15 @@
module ActiveSupport
- module Deprecation
- class << self
+ class Deprecation
+ module Reporting
+ # Whether to print a message (silent mode)
attr_accessor :silenced
+ # Name of gem where method is deprecated
+ attr_accessor :gem_name
# Outputs a deprecation warning to the output configured by
# <tt>ActiveSupport::Deprecation.behavior</tt>.
#
- # ActiveSupport::Deprecation.warn("something broke!")
+ # ActiveSupport::Deprecation.warn('something broke!')
# # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
def warn(message = nil, callstack = caller)
return if silenced
@@ -17,11 +20,11 @@ module ActiveSupport
# Silence deprecation warnings within the block.
#
- # ActiveSupport::Deprecation.warn("something broke!")
+ # ActiveSupport::Deprecation.warn('something broke!')
# # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
#
# ActiveSupport::Deprecation.silence do
- # ActiveSupport::Deprecation.warn("something broke!")
+ # ActiveSupport::Deprecation.warn('something broke!')
# end
# # => nil
def silence
@@ -31,16 +34,30 @@ module ActiveSupport
@silenced = old_silenced
end
- def deprecated_method_warning(method_name, message = nil)
- warning = "#{method_name} is deprecated and will be removed from Rails #{deprecation_horizon}"
- case message
- when Symbol then "#{warning} (use #{message} instead)"
- when String then "#{warning} (#{message})"
- else warning
+ def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = caller)
+ deprecated_method_warning(deprecated_method_name, message).tap do |msg|
+ warn(msg, caller_backtrace)
end
end
private
+ # Outputs a deprecation warning message
+ #
+ # ActiveSupport::Deprecation.deprecated_method_warning(:method_name)
+ # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon}"
+ # ActiveSupport::Deprecation.deprecated_method_warning(:method_name, :another_method)
+ # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (use another_method instead)"
+ # ActiveSupport::Deprecation.deprecated_method_warning(:method_name, "Optional message")
+ # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (Optional message)"
+ def deprecated_method_warning(method_name, message = nil)
+ warning = "#{method_name} is deprecated and will be removed from #{gem_name} #{deprecation_horizon}"
+ case message
+ when Symbol then "#{warning} (use #{message} instead)"
+ when String then "#{warning} (#{message})"
+ else warning
+ end
+ end
+
def deprecation_message(callstack, message = nil)
message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
message += '.' unless message =~ /\.$/
diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb
index a0139b7d8e..7e99646117 100644
--- a/activesupport/lib/active_support/duration.rb
+++ b/activesupport/lib/active_support/duration.rb
@@ -6,7 +6,7 @@ module ActiveSupport
# Provides accurate date and time measurements using Date#advance and
# Time#advance, respectively. It mainly supports the methods on Numeric.
#
- # 1.month.ago # equivalent to Time.now.advance(:months => -1)
+ # 1.month.ago # equivalent to Time.now.advance(months: -1)
class Duration < BasicObject
attr_accessor :value, :parts
@@ -39,8 +39,8 @@ module ActiveSupport
end
alias :kind_of? :is_a?
- # Returns true if <tt>other</tt> is also a Duration instance with the
- # same <tt>value</tt>, or if <tt>other == value</tt>.
+ # Returns +true+ if +other+ is also a Duration instance with the
+ # same +value+, or if <tt>other == value</tt>.
def ==(other)
if Duration === other
other.value == value
diff --git a/activesupport/lib/active_support/file_update_checker.rb b/activesupport/lib/active_support/file_update_checker.rb
index 1cc852a3e6..a6b9aa3503 100644
--- a/activesupport/lib/active_support/file_update_checker.rb
+++ b/activesupport/lib/active_support/file_update_checker.rb
@@ -1,23 +1,21 @@
module ActiveSupport
- # \FileUpdateChecker specifies the API used by Rails to watch files
+ # FileUpdateChecker specifies the API used by Rails to watch files
# and control reloading. The API depends on four methods:
#
# * +initialize+ which expects two parameters and one block as
- # described below;
+ # described below.
#
# * +updated?+ which returns a boolean if there were updates in
- # the filesystem or not;
+ # the filesystem or not.
#
# * +execute+ which executes the given block on initialization
- # and updates the latest watched files and timestamp;
+ # and updates the latest watched files and timestamp.
#
- # * +execute_if_updated+ which just executes the block if it was updated;
+ # * +execute_if_updated+ which just executes the block if it was updated.
#
# After initialization, a call to +execute_if_updated+ must execute
# the block only if there was really a change in the filesystem.
#
- # == Examples
- #
# This class is used by Rails to reload the I18n framework whenever
# they are changed upon a new request.
#
@@ -28,7 +26,6 @@ module ActiveSupport
# ActionDispatch::Reloader.to_prepare do
# i18n_reloader.execute_if_updated
# end
- #
class FileUpdateChecker
# It accepts two parameters on initialization. The first is an array
# of files and the second is an optional hash of directories. The hash must
@@ -52,7 +49,7 @@ module ActiveSupport
# Check if any of the entries were updated. If so, the watched and/or
# updated_at values are cached until the block is executed via +execute+
- # or +execute_if_updated+
+ # or +execute_if_updated+.
def updated?
current_watched = watched
if @last_watched.size != current_watched.size
@@ -70,7 +67,8 @@ module ActiveSupport
end
end
- # Executes the given block and updates the latest watched files and timestamp.
+ # Executes the given block and updates the latest watched files and
+ # timestamp.
def execute
@last_watched = watched
@last_update_at = updated_at(@last_watched)
diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb
index 5fd20673d8..0c78f1611f 100644
--- a/activesupport/lib/active_support/hash_with_indifferent_access.rb
+++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb
@@ -1,7 +1,8 @@
require 'active_support/core_ext/hash/keys'
module ActiveSupport
- # Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered to be the same.
+ # Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
+ # to be the same.
#
# rgb = ActiveSupport::HashWithIndifferentAccess.new
#
@@ -15,17 +16,17 @@ module ActiveSupport
#
# Internally symbols are mapped to strings when used as keys in the entire
# writing interface (calling <tt>[]=</tt>, <tt>merge</tt>, etc). This
- # mapping belongs to the public interface. For example, given
+ # mapping belongs to the public interface. For example, given:
#
- # hash = ActiveSupport::HashWithIndifferentAccess.new(:a => 1)
+ # hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
#
- # you are guaranteed that the key is returned as a string:
+ # You are guaranteed that the key is returned as a string:
#
# hash.keys # => ["a"]
#
# Technically other types of keys are accepted:
#
- # hash = ActiveSupport::HashWithIndifferentAccess.new(:a => 1)
+ # hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
# hash[0] = 0
# hash # => {"a"=>1, 0=>0}
#
@@ -35,11 +36,11 @@ module ActiveSupport
#
# Note that core extensions define <tt>Hash#with_indifferent_access</tt>:
#
- # rgb = {:black => '#000000', :white => '#FFFFFF'}.with_indifferent_access
+ # rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
#
# which may be handy.
class HashWithIndifferentAccess < Hash
- # Returns true so that <tt>Array#extract_options!</tt> finds members of
+ # Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
# this class.
def extractable_options?
true
@@ -86,22 +87,22 @@ module ActiveSupport
# Assigns a new value to the hash:
#
# hash = ActiveSupport::HashWithIndifferentAccess.new
- # hash[:key] = "value"
+ # hash[:key] = 'value'
#
- # This value can be later fetched using either +:key+ or +"key"+.
+ # This value can be later fetched using either +:key+ or +'key'+.
def []=(key, value)
regular_writer(convert_key(key), convert_value(value))
end
alias_method :store, :[]=
- # Updates the receiver in-place merging in the hash passed as argument:
+ # Updates the receiver in-place, merging in the hash passed as argument:
#
# hash_1 = ActiveSupport::HashWithIndifferentAccess.new
- # hash_2[:key] = "value"
+ # hash_1[:key] = 'value'
#
# hash_2 = ActiveSupport::HashWithIndifferentAccess.new
- # hash_2[:key] = "New Value!"
+ # hash_2[:key] = 'New Value!'
#
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
#
@@ -110,12 +111,26 @@ module ActiveSupport
# In either case the merge respects the semantics of indifferent access.
#
# If the argument is a regular hash with keys +:key+ and +"key"+ only one
- # of the values end up in the receiver, but which was is unespecified.
+ # of the values end up in the receiver, but which one is unspecified.
+ #
+ # When given a block, the value for duplicated keys will be determined
+ # by the result of invoking the block with the duplicated key, the value
+ # in the receiver, and the value in +other_hash+. The rules for duplicated
+ # keys follow the semantics of indifferent access:
+ #
+ # hash_1[:key] = 10
+ # hash_2['key'] = 12
+ # hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
def update(other_hash)
if other_hash.is_a? HashWithIndifferentAccess
super(other_hash)
else
- other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
+ other_hash.each_pair do |key, value|
+ if block_given? && key?(key)
+ value = yield(convert_key(key), self[key], value)
+ end
+ regular_writer(convert_key(key), convert_value(value))
+ end
self
end
end
@@ -125,10 +140,9 @@ module ActiveSupport
# Checks the hash for a key matching the argument passed in:
#
# hash = ActiveSupport::HashWithIndifferentAccess.new
- # hash["key"] = "value"
+ # hash['key'] = 'value'
# hash.key?(:key) # => true
- # hash.key?("key") # => true
- #
+ # hash.key?('key') # => true
def key?(key)
super(convert_key(key))
end
@@ -143,11 +157,10 @@ module ActiveSupport
# counters = ActiveSupport::HashWithIndifferentAccess.new
# counters[:foo] = 1
#
- # counters.fetch("foo") # => 1
+ # counters.fetch('foo') # => 1
# counters.fetch(:bar, 0) # => 0
# counters.fetch(:bar) {|key| 0} # => 0
# counters.fetch(:zoo) # => KeyError: key not found: "zoo"
- #
def fetch(key, *extras)
super(convert_key(key), *extras)
end
@@ -155,10 +168,9 @@ module ActiveSupport
# Returns an array of the values at the specified indices:
#
# hash = ActiveSupport::HashWithIndifferentAccess.new
- # hash[:a] = "x"
- # hash[:b] = "y"
- # hash.values_at("a", "b") # => ["x", "y"]
- #
+ # hash[:a] = 'x'
+ # hash[:b] = 'y'
+ # hash.values_at('a', 'b') # => ["x", "y"]
def values_at(*indices)
indices.collect {|key| self[convert_key(key)]}
end
@@ -173,8 +185,8 @@ module ActiveSupport
# This method has the same semantics of +update+, except it does not
# modify the receiver but rather returns a new hash with indifferent
# access with the result of the merge.
- def merge(hash)
- self.dup.update(hash)
+ def merge(hash, &block)
+ self.dup.update(hash, &block)
end
# Like +merge+ but the other way around: Merges the receiver into the
@@ -182,8 +194,7 @@ module ActiveSupport
#
# hash = ActiveSupport::HashWithIndifferentAccess.new
# hash['a'] = nil
- # hash.reverse_merge(:a => 0, :b => 1) # => {"a"=>nil, "b"=>1}
- #
+ # hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
def reverse_merge(other_hash)
super(self.class.new_from_hash_copying_default(other_hash))
end
diff --git a/activesupport/lib/active_support/i18n_railtie.rb b/activesupport/lib/active_support/i18n_railtie.rb
index f67b221024..890dd9380b 100644
--- a/activesupport/lib/active_support/i18n_railtie.rb
+++ b/activesupport/lib/active_support/i18n_railtie.rb
@@ -16,7 +16,7 @@ module I18n
end
# Trigger i18n config before any eager loading has happened
- # so it's ready if any classes require it when eager loaded
+ # so it's ready if any classes require it when eager loaded.
config.before_eager_load do |app|
I18n::Railtie.initialize_i18n(app)
end
@@ -25,7 +25,7 @@ module I18n
@i18n_inited = false
- # Setup i18n configuration
+ # Setup i18n configuration.
def self.initialize_i18n(app)
return if @i18n_inited
diff --git a/activesupport/lib/active_support/inflector/inflections.rb b/activesupport/lib/active_support/inflector/inflections.rb
index 091692e5a4..af506d6f2e 100644
--- a/activesupport/lib/active_support/inflector/inflections.rb
+++ b/activesupport/lib/active_support/inflector/inflections.rb
@@ -5,9 +5,10 @@ module ActiveSupport
module Inflector
extend self
- # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
- # inflection rules. If passed an optional locale, rules for other languages can be specified. The default locale is
- # <tt>:en</tt>. Only rules for English are provided.
+ # A singleton instance of this class is yielded by Inflector.inflections,
+ # which can then be used to specify additional inflection rules. If passed
+ # an optional locale, rules for other languages can be specified. The
+ # default locale is <tt>:en</tt>. Only rules for English are provided.
#
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, '\1\2en'
@@ -15,12 +16,13 @@ module ActiveSupport
#
# inflect.irregular 'octopus', 'octopi'
#
- # inflect.uncountable "equipment"
+ # inflect.uncountable 'equipment'
# end
#
- # New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
- # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
- # already have been loaded.
+ # New rules are added at the top. So in the example above, the irregular
+ # rule for octopus will now be the first of the pluralization and
+ # singularization rules that is runs. This guarantees that your rules run
+ # before any of the rules that may already have been loaded.
class Inflections
def self.instance(locale = :en)
@__instance__ ||= Hash.new { |h, k| h[k] = new }
@@ -34,36 +36,40 @@ module ActiveSupport
end
# Private, for the test suite.
- def initialize_dup(orig)
+ def initialize_dup(orig) # :nodoc:
%w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope|
instance_variable_set("@#{scope}", orig.send(scope).dup)
end
end
- # Specifies a new acronym. An acronym must be specified as it will appear in a camelized string. An underscore
- # string that contains the acronym will retain the acronym when passed to `camelize`, `humanize`, or `titleize`.
- # A camelized string that contains the acronym will maintain the acronym when titleized or humanized, and will
- # convert the acronym into a non-delimited single lowercase word when passed to +underscore+.
+ # Specifies a new acronym. An acronym must be specified as it will appear
+ # in a camelized string. An underscore string that contains the acronym
+ # will retain the acronym when passed to +camelize+, +humanize+, or
+ # +titleize+. A camelized string that contains the acronym will maintain
+ # the acronym when titleized or humanized, and will convert the acronym
+ # into a non-delimited single lowercase word when passed to +underscore+.
#
# acronym 'HTML'
- # titleize 'html' #=> 'HTML'
- # camelize 'html' #=> 'HTML'
+ # titleize 'html' #=> 'HTML'
+ # camelize 'html' #=> 'HTML'
# underscore 'MyHTML' #=> 'my_html'
#
- # The acronym, however, must occur as a delimited unit and not be part of another word for conversions to recognize it:
+ # The acronym, however, must occur as a delimited unit and not be part of
+ # another word for conversions to recognize it:
#
# acronym 'HTTP'
# camelize 'my_http_delimited' #=> 'MyHTTPDelimited'
- # camelize 'https' #=> 'Https', not 'HTTPs'
- # underscore 'HTTPS' #=> 'http_s', not 'https'
+ # camelize 'https' #=> 'Https', not 'HTTPs'
+ # underscore 'HTTPS' #=> 'http_s', not 'https'
#
# acronym 'HTTPS'
- # camelize 'https' #=> 'HTTPS'
+ # camelize 'https' #=> 'HTTPS'
# underscore 'HTTPS' #=> 'https'
#
- # Note: Acronyms that are passed to `pluralize` will no longer be recognized, since the acronym will not occur as
- # a delimited unit in the pluralized result. To work around this, you must specify the pluralized form as an
- # acronym as well:
+ # Note: Acronyms that are passed to +pluralize+ will no longer be
+ # recognized, since the acronym will not occur as a delimited unit in the
+ # pluralized result. To work around this, you must specify the pluralized
+ # form as an acronym as well:
#
# acronym 'API'
# camelize(pluralize('api')) #=> 'Apis'
@@ -71,42 +77,49 @@ module ActiveSupport
# acronym 'APIs'
# camelize(pluralize('api')) #=> 'APIs'
#
- # `acronym` may be used to specify any word that contains an acronym or otherwise needs to maintain a non-standard
- # capitalization. The only restriction is that the word must begin with a capital letter.
+ # +acronym+ may be used to specify any word that contains an acronym or
+ # otherwise needs to maintain a non-standard capitalization. The only
+ # restriction is that the word must begin with a capital letter.
#
# acronym 'RESTful'
- # underscore 'RESTful' #=> 'restful'
+ # underscore 'RESTful' #=> 'restful'
# underscore 'RESTfulController' #=> 'restful_controller'
- # titleize 'RESTfulController' #=> 'RESTful Controller'
- # camelize 'restful' #=> 'RESTful'
- # camelize 'restful_controller' #=> 'RESTfulController'
+ # titleize 'RESTfulController' #=> 'RESTful Controller'
+ # camelize 'restful' #=> 'RESTful'
+ # camelize 'restful_controller' #=> 'RESTfulController'
#
# acronym 'McDonald'
# underscore 'McDonald' #=> 'mcdonald'
- # camelize 'mcdonald' #=> 'McDonald'
+ # camelize 'mcdonald' #=> 'McDonald'
def acronym(word)
@acronyms[word.downcase] = word
@acronym_regex = /#{@acronyms.values.join("|")}/
end
- # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
- # The replacement should always be a string that may include references to the matched data from the rule.
+ # Specifies a new pluralization rule and its replacement. The rule can
+ # either be a string or a regular expression. The replacement should
+ # always be a string that may include references to the matched data from
+ # the rule.
def plural(rule, replacement)
@uncountables.delete(rule) if rule.is_a?(String)
@uncountables.delete(replacement)
@plurals.prepend([rule, replacement])
end
- # Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
- # The replacement should always be a string that may include references to the matched data from the rule.
+ # Specifies a new singularization rule and its replacement. The rule can
+ # either be a string or a regular expression. The replacement should
+ # always be a string that may include references to the matched data from
+ # the rule.
def singular(rule, replacement)
@uncountables.delete(rule) if rule.is_a?(String)
@uncountables.delete(replacement)
@singulars.prepend([rule, replacement])
end
- # Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
- # for strings, not regular expressions. You simply pass the irregular in singular and plural form.
+ # Specifies a new irregular that applies to both pluralization and
+ # singularization at the same time. This can only be used for strings, not
+ # regular expressions. You simply pass the irregular in singular and
+ # plural form.
#
# irregular 'octopus', 'octopi'
# irregular 'person', 'people'
@@ -129,26 +142,29 @@ module ActiveSupport
# Add uncountable words that shouldn't be attempted inflected.
#
- # uncountable "money"
- # uncountable "money", "information"
+ # uncountable 'money'
+ # uncountable 'money', 'information'
# uncountable %w( money information rice )
def uncountable(*words)
(@uncountables << words).flatten!
end
- # Specifies a humanized form of a string by a regular expression rule or by a string mapping.
- # When using a regular expression based replacement, the normal humanize formatting is called after the replacement.
- # When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name')
+ # Specifies a humanized form of a string by a regular expression rule or
+ # by a string mapping. When using a regular expression based replacement,
+ # the normal humanize formatting is called after the replacement. When a
+ # string is used, the human form should be specified as desired (example:
+ # 'The name', not 'the_name').
#
# human /_cnt$/i, '\1_count'
- # human "legacy_col_person_name", "Name"
+ # human 'legacy_col_person_name', 'Name'
def human(rule, replacement)
@humans.prepend([rule, replacement])
end
- # 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>, <tt>:humans</tt>.
+ # 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>,
+ # <tt>:humans</tt>.
#
# clear :all
# clear :plurals
@@ -162,13 +178,13 @@ module ActiveSupport
end
end
- # Yields a singleton instance of Inflector::Inflections so you can specify additional
- # inflector rules. If passed an optional locale, rules for other languages can be specified.
- # If not specified, defaults to <tt>:en</tt>. Only rules for English are provided.
- #
+ # Yields a singleton instance of Inflector::Inflections so you can specify
+ # additional inflector rules. If passed an optional locale, rules for other
+ # languages can be specified. If not specified, defaults to <tt>:en</tt>.
+ # Only rules for English are provided.
#
# ActiveSupport::Inflector.inflections(:en) do |inflect|
- # inflect.uncountable "rails"
+ # inflect.uncountable 'rails'
# end
def inflections(locale = :en)
if block_given?
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index 44214d16fa..3910a2dc42 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -4,14 +4,16 @@ require 'active_support/inflector/inflections'
require 'active_support/inflections'
module ActiveSupport
- # The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
- # and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
- # in inflections.rb.
+ # The Inflector transforms words from singular to plural, class names to table
+ # names, modularized class names to ones without, and class names to foreign
+ # keys. The default inflections for pluralization, singularization, and
+ # uncountable words are kept in inflections.rb.
#
- # The Rails core team has stated patches for the inflections library will not be accepted
- # in order to avoid breaking legacy applications which may be relying on errant inflections.
- # If you discover an incorrect inflection and require it for your application or wish to
- # define rules for languages other than English, please correct or add them yourself (explained below).
+ # The Rails core team has stated patches for the inflections library will not
+ # be accepted in order to avoid breaking legacy applications which may be
+ # relying on errant inflections. If you discover an incorrect inflection and
+ # require it for your application or wish to define rules for languages other
+ # than English, please correct or add them yourself (explained below).
module Inflector
extend self
@@ -21,46 +23,49 @@ module ActiveSupport
# pluralized using rules defined for that language. By default,
# this parameter is set to <tt>:en</tt>.
#
- # "post".pluralize # => "posts"
- # "octopus".pluralize # => "octopi"
- # "sheep".pluralize # => "sheep"
- # "words".pluralize # => "words"
- # "CamelOctopus".pluralize # => "CamelOctopi"
- # "ley".pluralize(:es) # => "leyes"
+ # 'post'.pluralize # => "posts"
+ # 'octopus'.pluralize # => "octopi"
+ # 'sheep'.pluralize # => "sheep"
+ # 'words'.pluralize # => "words"
+ # 'CamelOctopus'.pluralize # => "CamelOctopi"
+ # 'ley'.pluralize(:es) # => "leyes"
def pluralize(word, locale = :en)
apply_inflections(word, inflections(locale).plurals)
end
- # The reverse of +pluralize+, returns the singular form of a word in a string.
+ # The reverse of +pluralize+, returns the singular form of a word in a
+ # string.
#
# If passed an optional +locale+ parameter, the word will be
# pluralized using rules defined for that language. By default,
# this parameter is set to <tt>:en</tt>.
#
- # "posts".singularize # => "post"
- # "octopi".singularize # => "octopus"
- # "sheep".singularize # => "sheep"
- # "word".singularize # => "word"
- # "CamelOctopi".singularize # => "CamelOctopus"
- # "leyes".singularize(:es) # => "ley"
+ # 'posts'.singularize # => "post"
+ # 'octopi'.singularize # => "octopus"
+ # 'sheep'.singularize # => "sheep"
+ # 'word'.singularize # => "word"
+ # 'CamelOctopi'.singularize # => "CamelOctopus"
+ # 'leyes'.singularize(:es) # => "ley"
def singularize(word, locale = :en)
apply_inflections(word, inflections(locale).singulars)
end
- # By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
- # is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
+ # By default, +camelize+ converts strings to UpperCamelCase. If the argument
+ # to +camelize+ is set to <tt>:lower</tt> then +camelize+ produces
+ # lowerCamelCase.
#
- # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
+ # +camelize+ will also convert '/' to '::' which is useful for converting
+ # paths to namespaces.
#
- # "active_model".camelize # => "ActiveModel"
- # "active_model".camelize(:lower) # => "activeModel"
- # "active_model/errors".camelize # => "ActiveModel::Errors"
- # "active_model/errors".camelize(:lower) # => "activeModel::Errors"
+ # 'active_model'.camelize # => "ActiveModel"
+ # 'active_model'.camelize(:lower) # => "activeModel"
+ # 'active_model/errors'.camelize # => "ActiveModel::Errors"
+ # 'active_model/errors'.camelize(:lower) # => "activeModel::Errors"
#
- # As a rule of thumb you can think of +camelize+ as the inverse of +underscore+,
- # though there are cases where that does not hold:
+ # As a rule of thumb you can think of +camelize+ as the inverse of
+ # +underscore+, though there are cases where that does not hold:
#
- # "SSLError".underscore.camelize # => "SslError"
+ # 'SSLError'.underscore.camelize # => "SslError"
def camelize(term, uppercase_first_letter = true)
string = term.to_s
if uppercase_first_letter
@@ -75,13 +80,13 @@ module ActiveSupport
#
# Changes '::' to '/' to convert namespaces to paths.
#
- # "ActiveModel".underscore # => "active_model"
- # "ActiveModel::Errors".underscore # => "active_model/errors"
+ # 'ActiveModel'.underscore # => "active_model"
+ # 'ActiveModel::Errors'.underscore # => "active_model/errors"
#
- # As a rule of thumb you can think of +underscore+ as the inverse of +camelize+,
- # though there are cases where that does not hold:
+ # As a rule of thumb you can think of +underscore+ as the inverse of
+ # +camelize+, though there are cases where that does not hold:
#
- # "SSLError".underscore.camelize # => "SslError"
+ # 'SSLError'.underscore.camelize # => "SslError"
def underscore(camel_cased_word)
word = camel_cased_word.to_s.dup
word.gsub!('::', '/')
@@ -94,10 +99,11 @@ module ActiveSupport
end
# Capitalizes the first word and turns underscores into spaces and strips a
- # trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
+ # trailing "_id", if any. Like +titleize+, this is meant for creating pretty
+ # output.
#
- # "employee_salary" # => "Employee salary"
- # "author_id" # => "Author"
+ # 'employee_salary'.humanize # => "Employee salary"
+ # 'author_id'.humanize # => "Author"
def humanize(lower_case_and_underscored_word)
result = lower_case_and_underscored_word.to_s.dup
inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
@@ -108,39 +114,40 @@ module ActiveSupport
}.gsub(/^\w/) { $&.upcase }
end
- # Capitalizes all the words and replaces some characters in the string to create
- # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
- # used in the Rails internals.
+ # Capitalizes all the words and replaces some characters in the string to
+ # create a nicer looking title. +titleize+ is meant for creating pretty
+ # output. It is not used in the Rails internals.
#
# +titleize+ is also aliased as +titlecase+.
#
- # "man from the boondocks".titleize # => "Man From The Boondocks"
- # "x-men: the last stand".titleize # => "X Men: The Last Stand"
- # "TheManWithoutAPast".titleize # => "The Man Without A Past"
- # "raiders_of_the_lost_ark".titleize # => "Raiders Of The Lost Ark"
+ # 'man from the boondocks'.titleize # => "Man From The Boondocks"
+ # 'x-men: the last stand'.titleize # => "X Men: The Last Stand"
+ # 'TheManWithoutAPast'.titleize # => "The Man Without A Past"
+ # 'raiders_of_the_lost_ark'.titleize # => "Raiders Of The Lost Ark"
def titleize(word)
humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) { $&.capitalize }
end
- # Create the name of a table like Rails does for models to table names. This method
- # uses the +pluralize+ method on the last word in the string.
+ # Create the name of a table like Rails does for models to table names. This
+ # method uses the +pluralize+ method on the last word in the string.
#
- # "RawScaledScorer".tableize # => "raw_scaled_scorers"
- # "egg_and_ham".tableize # => "egg_and_hams"
- # "fancyCategory".tableize # => "fancy_categories"
+ # 'RawScaledScorer'.tableize # => "raw_scaled_scorers"
+ # 'egg_and_ham'.tableize # => "egg_and_hams"
+ # 'fancyCategory'.tableize # => "fancy_categories"
def tableize(class_name)
pluralize(underscore(class_name))
end
- # Create a class name from a plural table name like Rails does for table names to models.
- # Note that this returns a string and not a Class. (To convert to an actual class
- # follow +classify+ with +constantize+.)
+ # Create a class name from a plural table name like Rails does for table
+ # names to models. Note that this returns a string and not a Class (To
+ # convert to an actual class follow +classify+ with +constantize+).
#
- # "egg_and_hams".classify # => "EggAndHam"
- # "posts".classify # => "Post"
+ # 'egg_and_hams'.classify # => "EggAndHam"
+ # 'posts'.classify # => "Post"
#
# Singular names are not handled correctly:
- # "business".classify # => "Busines"
+ #
+ # 'business'.classify # => "Busines"
def classify(table_name)
# strip out any leading schema name
camelize(singularize(table_name.to_s.sub(/.*\./, '')))
@@ -148,15 +155,15 @@ module ActiveSupport
# Replaces underscores with dashes in the string.
#
- # "puni_puni".dasherize # => "puni-puni"
+ # 'puni_puni'.dasherize # => "puni-puni"
def dasherize(underscored_word)
underscored_word.tr('_', '-')
end
- # Removes the module part from the expression in the string:
+ # Removes the module part from the expression in the string.
#
- # "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
- # "Inflections".demodulize # => "Inflections"
+ # 'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
+ # 'Inflections'.demodulize # => "Inflections"
#
# See also +deconstantize+.
def demodulize(path)
@@ -168,13 +175,13 @@ module ActiveSupport
end
end
- # Removes the rightmost segment from the constant expression in the string:
+ # Removes the rightmost segment from the constant expression in the string.
#
- # "Net::HTTP".deconstantize # => "Net"
- # "::Net::HTTP".deconstantize # => "::Net"
- # "String".deconstantize # => ""
- # "::String".deconstantize # => ""
- # "".deconstantize # => ""
+ # 'Net::HTTP'.deconstantize # => "Net"
+ # '::Net::HTTP'.deconstantize # => "::Net"
+ # 'String'.deconstantize # => ""
+ # '::String'.deconstantize # => ""
+ # ''.deconstantize # => ""
#
# See also +demodulize+.
def deconstantize(path)
@@ -185,26 +192,27 @@ module ActiveSupport
# +separate_class_name_and_id_with_underscore+ sets whether
# the method should put '_' between the name and 'id'.
#
- # "Message".foreign_key # => "message_id"
- # "Message".foreign_key(false) # => "messageid"
- # "Admin::Post".foreign_key # => "post_id"
+ # 'Message'.foreign_key # => "message_id"
+ # 'Message'.foreign_key(false) # => "messageid"
+ # 'Admin::Post'.foreign_key # => "post_id"
def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
end
- # Tries to find a constant with the name specified in the argument string:
+ # Tries to find a constant with the name specified in the argument string.
#
- # "Module".constantize # => Module
- # "Test::Unit".constantize # => Test::Unit
+ # '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:
+ # 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
+ # 'C'.constantize # => 'outside', same as ::C
# end
#
# NameError is raised when the name is not in CamelCase or the constant is
@@ -235,28 +243,28 @@ module ActiveSupport
end
end
- # Tries to find a constant with the name specified in the argument string:
+ # Tries to find a constant with the name specified in the argument string.
#
- # "Module".safe_constantize # => Module
- # "Test::Unit".safe_constantize # => Test::Unit
+ # 'Module'.safe_constantize # => Module
+ # 'Test::Unit'.safe_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:
+ # 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".safe_constantize # => 'outside', same as ::C
+ # 'C'.safe_constantize # => 'outside', same as ::C
# end
#
- # nil is returned when the name is not in CamelCase or the constant (or part of it) is
- # unknown.
- #
- # "blargle".safe_constantize # => nil
- # "UnknownModule".safe_constantize # => nil
- # "UnknownModule::Foo::Bar".safe_constantize # => nil
+ # +nil+ is returned when the name is not in CamelCase or the constant (or
+ # part of it) is unknown.
#
+ # 'blargle'.safe_constantize # => nil
+ # 'UnknownModule'.safe_constantize # => nil
+ # 'UnknownModule::Foo::Bar'.safe_constantize # => nil
def safe_constantize(camel_cased_word)
begin
constantize(camel_cased_word)
@@ -318,8 +326,8 @@ module ActiveSupport
# Applies inflection rules for +singularize+ and +pluralize+.
#
- # apply_inflections("post", inflections.plurals) # => "posts"
- # apply_inflections("posts", inflections.singulars) # => "post"
+ # apply_inflections('post', inflections.plurals) # => "posts"
+ # apply_inflections('posts', inflections.singulars) # => "post"
def apply_inflections(word, rules)
result = word.to_s.dup
diff --git a/activesupport/lib/active_support/inflector/transliterate.rb b/activesupport/lib/active_support/inflector/transliterate.rb
index a372b6d1f7..1cde417fc5 100644
--- a/activesupport/lib/active_support/inflector/transliterate.rb
+++ b/activesupport/lib/active_support/inflector/transliterate.rb
@@ -8,7 +8,7 @@ module ActiveSupport
# Replaces non-ASCII characters with an ASCII approximation, or if none
# exists, a replacement character which defaults to "?".
#
- # transliterate("Ærøskøbing")
+ # transliterate('Ærøskøbing')
# # => "AEroskobing"
#
# Default approximations are provided for Western/Latin characters,
@@ -30,33 +30,33 @@ module ActiveSupport
# ö: "oe"
#
# # Or set them using Ruby
- # I18n.backend.store_translations(:de, :i18n => {
- # :transliterate => {
- # :rule => {
- # "ü" => "ue",
- # "ö" => "oe"
+ # I18n.backend.store_translations(:de, i18n: {
+ # transliterate: {
+ # rule: {
+ # 'ü' => 'ue',
+ # 'ö' => 'oe'
# }
# }
# })
#
- # The value for <tt>i18n.transliterate.rule</tt> can be a simple Hash that maps
- # characters to ASCII approximations as shown above, or, for more complex
- # requirements, a Proc:
+ # The value for <tt>i18n.transliterate.rule</tt> can be a simple Hash that
+ # maps characters to ASCII approximations as shown above, or, for more
+ # complex requirements, a Proc:
#
- # I18n.backend.store_translations(:de, :i18n => {
- # :transliterate => {
- # :rule => lambda {|string| MyTransliterator.transliterate(string)}
+ # I18n.backend.store_translations(:de, i18n: {
+ # transliterate: {
+ # rule: ->(string) { MyTransliterator.transliterate(string) }
# }
# })
#
# Now you can have different transliterations for each locale:
#
# I18n.locale = :en
- # transliterate("Jürgen")
+ # transliterate('Jürgen')
# # => "Jurgen"
#
# I18n.locale = :de
- # transliterate("Jürgen")
+ # transliterate('Jürgen')
# # => "Juergen"
def transliterate(string, replacement = "?")
I18n.transliterate(ActiveSupport::Multibyte::Unicode.normalize(
@@ -64,7 +64,8 @@ module ActiveSupport
:replacement => replacement)
end
- # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
+ # Replaces special characters in a string so that it may be used as part of
+ # a 'pretty' URL.
#
# class Person
# def to_param
diff --git a/activesupport/lib/active_support/json/decoding.rb b/activesupport/lib/active_support/json/decoding.rb
index e44939e78a..a4a32b2ad0 100644
--- a/activesupport/lib/active_support/json/decoding.rb
+++ b/activesupport/lib/active_support/json/decoding.rb
@@ -39,8 +39,10 @@ module ActiveSupport
self.backend = old_backend
end
- # Returns the class of the error that will be raised when there is an error in decoding JSON.
- # Using this method means you won't directly depend on the ActiveSupport's JSON implementation, in case it changes in the future.
+ # Returns the class of the error that will be raised when there is an
+ # error in decoding JSON. Using this method means you won't directly
+ # depend on the ActiveSupport's JSON implementation, in case it changes
+ # in the future.
#
# begin
# obj = ActiveSupport::JSON.decode(some_string)
diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb
index 1a95bd63e6..f65c831e04 100644
--- a/activesupport/lib/active_support/json/encoding.rb
+++ b/activesupport/lib/active_support/json/encoding.rb
@@ -25,9 +25,10 @@ module ActiveSupport
# matches YAML-formatted dates
DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
- # Dumps objects in JSON (JavaScript Object Notation). See www.json.org for more info.
+ # Dumps objects in JSON (JavaScript Object Notation).
+ # See www.json.org for more info.
#
- # ActiveSupport::JSON.encode({team: 'rails', players: '36'})
+ # ActiveSupport::JSON.encode({ team: 'rails', players: '36' })
# # => "{\"team\":\"rails\",\"players\":\"36\"}"
def self.encode(value, options = nil)
Encoding::Encoder.new(options).encode(value)
@@ -51,7 +52,7 @@ module ActiveSupport
end
end
- # like encode, but only calls as_json, without encoding to string
+ # like encode, but only calls as_json, without encoding to string.
def as_json(value, use_options = true)
check_for_circular_references(value) do
use_options ? value.as_json(options_for(value)) : value.as_json
@@ -60,7 +61,8 @@ module ActiveSupport
def options_for(value)
if value.is_a?(Array) || value.is_a?(Hash)
- # hashes and arrays need to get encoder in the options, so that they can detect circular references
+ # hashes and arrays need to get encoder in the options, so that
+ # they can detect circular references.
options.merge(:encoder => self)
else
options
@@ -105,10 +107,12 @@ module ActiveSupport
'&' => '\u0026' }
class << self
- # If true, use ISO 8601 format for dates and times. Otherwise, fall back to the Active Support legacy format.
+ # If true, use ISO 8601 format for dates and times. Otherwise, fall back
+ # to the Active Support legacy format.
attr_accessor :use_standard_json_time_format
- # If false, serializes BigDecimal objects as numeric instead of wrapping them in a string
+ # If false, serializes BigDecimal objects as numeric instead of wrapping
+ # them in a string.
attr_accessor :encode_big_decimal_as_string
attr_accessor :escape_regex
@@ -231,11 +235,13 @@ class BigDecimal
# those libraries would get in general a wrong number and no way to recover
# other than manually inspecting the string with the JSON code itself.
#
- # That's why a JSON string is returned. The JSON literal is not numeric, but if
- # the other end knows by contract that the data is supposed to be a BigDecimal,
- # it still has the chance to post-process the string and get the real value.
+ # That's why a JSON string is returned. The JSON literal is not numeric, but
+ # if the other end knows by contract that the data is supposed to be a
+ # BigDecimal, it still has the chance to post-process the string and get the
+ # real value.
#
- # Use ActiveSupport.use_standard_json_big_decimal_format = true to override this behaviour
+ # Use <tt>ActiveSupport.use_standard_json_big_decimal_format = true</tt> to
+ # override this behaviour.
def as_json(options = nil) #:nodoc:
if finite?
ActiveSupport.encode_big_decimal_as_string ? to_s : self
diff --git a/activesupport/lib/active_support/lazy_load_hooks.rb b/activesupport/lib/active_support/lazy_load_hooks.rb
index c167efc1a7..e489512531 100644
--- a/activesupport/lib/active_support/lazy_load_hooks.rb
+++ b/activesupport/lib/active_support/lazy_load_hooks.rb
@@ -1,23 +1,25 @@
module ActiveSupport
- # lazy_load_hooks allows rails to lazily load a lot of components and thus making the app boot faster. Because of
- # this feature now there is no need to require <tt>ActiveRecord::Base</tt> at boot time purely to apply configuration. Instead
- # a hook is registered that applies configuration once <tt>ActiveRecord::Base</tt> is loaded. Here <tt>ActiveRecord::Base</tt> is used
- # as example but this feature can be applied elsewhere too.
+ # lazy_load_hooks allows rails to lazily load a lot of components and thus
+ # making the app boot faster. Because of this feature now there is no need to
+ # require <tt>ActiveRecord::Base</tt> at boot time purely to apply
+ # configuration. Instead a hook is registered that applies configuration once
+ # <tt>ActiveRecord::Base</tt> is loaded. Here <tt>ActiveRecord::Base</tt> is
+ # used as example but this feature can be applied elsewhere too.
#
# Here is an example where +on_load+ method is called to register a hook.
#
- # initializer "active_record.initialize_timezone" do
+ # initializer 'active_record.initialize_timezone' do
# ActiveSupport.on_load(:active_record) do
# self.time_zone_aware_attributes = true
# self.default_timezone = :utc
# end
# end
#
- # When the entirety of +activerecord/lib/active_record/base.rb+ has been evaluated then +run_load_hooks+ is invoked.
- # The very last line of +activerecord/lib/active_record/base.rb+ is:
+ # When the entirety of +activerecord/lib/active_record/base.rb+ has been
+ # evaluated then +run_load_hooks+ is invoked. The very last line of
+ # +activerecord/lib/active_record/base.rb+ is:
#
# ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
- #
@load_hooks = Hash.new { |h,k| h[k] = [] }
@loaded = Hash.new { |h,k| h[k] = [] }
diff --git a/activesupport/lib/active_support/log_subscriber.rb b/activesupport/lib/active_support/log_subscriber.rb
index e5b4ca2738..a58afc6b9d 100644
--- a/activesupport/lib/active_support/log_subscriber.rb
+++ b/activesupport/lib/active_support/log_subscriber.rb
@@ -2,11 +2,13 @@ require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/class/attribute'
module ActiveSupport
- # ActiveSupport::LogSubscriber is an object set to consume ActiveSupport::Notifications
- # with the sole purpose of logging them. The log subscriber dispatches notifications to
- # a registered object based on its given namespace.
+ # ActiveSupport::LogSubscriber is an object set to consume
+ # ActiveSupport::Notifications with the sole purpose of logging them.
+ # The log subscriber dispatches notifications to a registered object based
+ # on its given namespace.
#
- # An example would be Active Record log subscriber responsible for logging queries:
+ # An example would be Active Record log subscriber responsible for logging
+ # queries:
#
# module ActiveRecord
# class LogSubscriber < ActiveSupport::LogSubscriber
@@ -20,16 +22,17 @@ module ActiveSupport
#
# ActiveRecord::LogSubscriber.attach_to :active_record
#
- # Since we need to know all instance methods before attaching the log subscriber,
- # the line above should be called after your <tt>ActiveRecord::LogSubscriber</tt> definition.
+ # Since we need to know all instance methods before attaching the log
+ # subscriber, the line above should be called after your
+ # <tt>ActiveRecord::LogSubscriber</tt> definition.
#
# After configured, whenever a "sql.active_record" notification is published,
# it will properly dispatch the event (ActiveSupport::Notifications::Event) to
# the sql method.
#
- # Log subscriber also has some helpers to deal with logging and automatically flushes
- # all logs when the request finishes (via action_dispatch.callback notification) in
- # a Rails environment.
+ # Log subscriber also has some helpers to deal with logging and automatically
+ # flushes all logs when the request finishes (via action_dispatch.callback
+ # notification) in a Rails environment.
class LogSubscriber
# Embed in a String to clear all previous ANSI sequences.
CLEAR = "\e[0m"
@@ -122,10 +125,9 @@ module ActiveSupport
end
# Set color by using a string or one of the defined constants. If a third
- # option is set to true, it also adds bold to the string. This is based
+ # option is set to +true+, it also adds bold to the string. This is based
# on the Highline implementation and will automatically append CLEAR to the
# end of the returned String.
- #
def color(text, color, bold=false)
return text unless colorize_logging
color = self.class.const_get(color.upcase) if color.is_a?(Symbol)
diff --git a/activesupport/lib/active_support/log_subscriber/test_helper.rb b/activesupport/lib/active_support/log_subscriber/test_helper.rb
index b65ea6208c..63dad7e01a 100644
--- a/activesupport/lib/active_support/log_subscriber/test_helper.rb
+++ b/activesupport/lib/active_support/log_subscriber/test_helper.rb
@@ -23,15 +23,15 @@ module ActiveSupport
# end
# end
#
- # All you need to do is to ensure that your log subscriber is added to Rails::Subscriber,
- # as in the second line of the code above. The test helpers are responsible for setting
- # up the queue, subscriptions and turning colors in logs off.
- #
- # The messages are available in the @logger instance, which is a logger with limited
- # powers (it actually does not send anything to your output), and you can collect them
- # doing @logger.logged(level), where level is the level used in logging, like info,
- # debug, warn and so on.
+ # All you need to do is to ensure that your log subscriber is added to
+ # Rails::Subscriber, as in the second line of the code above. The test
+ # helpers are responsible for setting up the queue, subscriptions and
+ # turning colors in logs off.
#
+ # The messages are available in the @logger instance, which is a logger with
+ # limited powers (it actually does not send anything to your output), and
+ # you can collect them doing @logger.logged(level), where level is the level
+ # used in logging, like info, debug, warn and so on.
module TestHelper
def setup
@logger = MockLogger.new
@@ -91,12 +91,11 @@ module ActiveSupport
@notifier.wait
end
- # Overwrite if you use another logger in your log subscriber:
+ # Overwrite if you use another logger in your log subscriber.
#
# def logger
# ActiveRecord::Base.logger = @logger
# end
- #
def set_logger(logger)
ActiveSupport::LogSubscriber.logger = logger
end
diff --git a/activesupport/lib/active_support/logger.rb b/activesupport/lib/active_support/logger.rb
index d055767eab..65202f99fc 100644
--- a/activesupport/lib/active_support/logger.rb
+++ b/activesupport/lib/active_support/logger.rb
@@ -2,7 +2,7 @@ require 'logger'
module ActiveSupport
class Logger < ::Logger
- # Broadcasts logs to multiple loggers
+ # Broadcasts logs to multiple loggers.
def self.broadcast(logger) # :nodoc:
Module.new do
define_method(:add) do |*args, &block|
diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb
index ada2e79ccb..580267708c 100644
--- a/activesupport/lib/active_support/message_encryptor.rb
+++ b/activesupport/lib/active_support/message_encryptor.rb
@@ -2,18 +2,19 @@ require 'openssl'
require 'base64'
module ActiveSupport
- # MessageEncryptor is a simple way to encrypt values which get stored somewhere
- # you don't trust.
+ # MessageEncryptor is a simple way to encrypt values which get stored
+ # somewhere you don't trust.
#
- # The cipher text and initialization vector are base64 encoded and returned to you.
+ # The cipher text and initialization vector are base64 encoded and returned
+ # to you.
#
- # This can be used in situations similar to the <tt>MessageVerifier</tt>, but where you don't
- # want users to be able to determine the value of the payload.
+ # This can be used in situations similar to the <tt>MessageVerifier</tt>, but
+ # where you don't want users to be able to determine the value of the payload.
#
- # key = OpenSSL::Digest::SHA256.new('password').digest # => "\x89\xE0\x156\xAC..."
- # crypt = ActiveSupport::MessageEncryptor.new(key) # => #<ActiveSupport::MessageEncryptor ...>
- # encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
- # crypt.decrypt_and_verify(encrypted_data) # => "my secret data"
+ # key = OpenSSL::Digest::SHA256.new('password').digest # => "\x89\xE0\x156\xAC..."
+ # crypt = ActiveSupport::MessageEncryptor.new(key) # => #<ActiveSupport::MessageEncryptor ...>
+ # encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
+ # crypt.decrypt_and_verify(encrypted_data) # => "my secret data"
class MessageEncryptor
module NullSerializer #:nodoc:
def self.load(value)
@@ -28,15 +29,16 @@ module ActiveSupport
class InvalidMessage < StandardError; end
OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError
- # Initialize a new MessageEncryptor.
- # +secret+ must be at least as long as the cipher key size. For the default 'aes-256-cbc' cipher,
- # this is 256 bits. If you are using a user-entered secret, you can generate a suitable key with
- # <tt>OpenSSL::Digest::SHA256.new(user_secret).digest</tt> or similar.
+ # Initialize a new MessageEncryptor. +secret+ must be at least as long as
+ # the cipher key size. For the default 'aes-256-cbc' cipher, this is 256
+ # bits. If you are using a user-entered secret, you can generate a suitable
+ # key with <tt>OpenSSL::Digest::SHA256.new(user_secret).digest</tt> or
+ # similar.
#
# Options:
- # * <tt>:cipher</tt> - Cipher to use. Can be any cipher returned by <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-cbc'
- # * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+.
- #
+ # * <tt>:cipher</tt> - Cipher to use. Can be any cipher returned by
+ # <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-cbc'.
+ # * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+.
def initialize(secret, options = {})
@secret = secret
@cipher = options[:cipher] || 'aes-256-cbc'
@@ -44,14 +46,14 @@ module ActiveSupport
@serializer = options[:serializer] || Marshal
end
- # Encrypt and sign a message. We need to sign the message in order to avoid padding attacks.
- # Reference: http://www.limited-entropy.com/padding-oracle-attacks
+ # Encrypt and sign a message. We need to sign the message in order to avoid
+ # padding attacks. Reference: http://www.limited-entropy.com/padding-oracle-attacks.
def encrypt_and_sign(value)
verifier.generate(_encrypt(value))
end
- # Decrypt and verify a message. We need to verify the message in order to avoid padding attacks.
- # Reference: http://www.limited-entropy.com/padding-oracle-attacks
+ # Decrypt and verify a message. We need to verify the message in order to
+ # avoid padding attacks. Reference: http://www.limited-entropy.com/padding-oracle-attacks.
def decrypt_and_verify(value)
_decrypt(verifier.verify(value))
end
diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb
index 3b27089fa0..140b6ca08d 100644
--- a/activesupport/lib/active_support/message_verifier.rb
+++ b/activesupport/lib/active_support/message_verifier.rb
@@ -2,11 +2,11 @@ require 'base64'
require 'active_support/core_ext/object/blank'
module ActiveSupport
- # +MessageVerifier+ makes it easy to generate and verify messages which are signed
- # to prevent tampering.
+ # +MessageVerifier+ makes it easy to generate and verify messages which are
+ # signed to prevent tampering.
#
- # This is useful for cases like remember-me tokens and auto-unsubscribe links where the
- # session store isn't suitable or available.
+ # This is useful for cases like remember-me tokens and auto-unsubscribe links
+ # where the session store isn't suitable or available.
#
# Remember Me:
# cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])
@@ -18,9 +18,9 @@ module ActiveSupport
# self.current_user = User.find(id)
# end
#
- # By default it uses Marshal to serialize the message. If you want to use another
- # serialization method, you can set the serializer attribute to something that responds
- # to dump and load, e.g.:
+ # By default it uses Marshal to serialize the message. If you want to use
+ # another serialization method, you can set the serializer attribute to
+ # something that responds to dump and load, e.g.:
#
# @verifier.serializer = YAML
class MessageVerifier
diff --git a/activesupport/lib/active_support/multibyte.rb b/activesupport/lib/active_support/multibyte.rb
index 977fe95dbe..1bf8e618ad 100644
--- a/activesupport/lib/active_support/multibyte.rb
+++ b/activesupport/lib/active_support/multibyte.rb
@@ -3,16 +3,17 @@ module ActiveSupport #:nodoc:
autoload :Chars, 'active_support/multibyte/chars'
autoload :Unicode, 'active_support/multibyte/unicode'
- # The proxy class returned when calling mb_chars. You can use this accessor to configure your own proxy
- # class so you can support other encodings. See the ActiveSupport::Multibyte::Chars implementation for
- # an example how to do this.
+ # The proxy class returned when calling mb_chars. You can use this accessor
+ # to configure your own proxy class so you can support other encodings. See
+ # the ActiveSupport::Multibyte::Chars implementation for an example how to
+ # do this.
#
# ActiveSupport::Multibyte.proxy_class = CharsForUTF32
def self.proxy_class=(klass)
@proxy_class = klass
end
- # Returns the current proxy class
+ # Returns the current proxy class.
def self.proxy_class
@proxy_class ||= ActiveSupport::Multibyte::Chars
end
diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb
index 47336d2143..a42e7f6542 100644
--- a/activesupport/lib/active_support/multibyte/chars.rb
+++ b/activesupport/lib/active_support/multibyte/chars.rb
@@ -6,22 +6,27 @@ require 'active_support/core_ext/module/delegation'
module ActiveSupport #:nodoc:
module Multibyte #:nodoc:
- # Chars enables you to work transparently with UTF-8 encoding in the Ruby String class without having extensive
- # knowledge about the encoding. A Chars object accepts a string upon initialization and proxies String methods in an
- # encoding safe manner. All the normal String methods are also implemented on the proxy.
+ # Chars enables you to work transparently with UTF-8 encoding in the Ruby
+ # String class without having extensive knowledge about the encoding. A
+ # Chars object accepts a string upon initialization and proxies String
+ # methods in an encoding safe manner. All the normal String methods are also
+ # implemented on the proxy.
#
- # String methods are proxied through the Chars object, and can be accessed through the +mb_chars+ method. Methods
- # which would normally return a String object now return a Chars object so methods can be chained.
+ # String methods are proxied through the Chars object, and can be accessed
+ # through the +mb_chars+ method. Methods which would normally return a
+ # String object now return a Chars object so methods can be chained.
#
- # "The Perfect String ".mb_chars.downcase.strip.normalize # => "the perfect string"
+ # 'The Perfect String '.mb_chars.downcase.strip.normalize # => "the perfect string"
#
- # Chars objects are perfectly interchangeable with String objects as long as no explicit class checks are made.
- # If certain methods do explicitly check the class, call +to_s+ before you pass chars objects to them.
+ # Chars objects are perfectly interchangeable with String objects as long as
+ # no explicit class checks are made. If certain methods do explicitly check
+ # the class, call +to_s+ before you pass chars objects to them.
#
- # bad.explicit_checking_method "T".mb_chars.downcase.to_s
+ # bad.explicit_checking_method 'T'.mb_chars.downcase.to_s
#
- # The default Chars implementation assumes that the encoding of the string is UTF-8, if you want to handle different
- # encodings you can write your own multibyte string handler and configure it through
+ # The default Chars implementation assumes that the encoding of the string
+ # is UTF-8, if you want to handle different encodings you can write your own
+ # multibyte string handler and configure it through
# ActiveSupport::Multibyte.proxy_class.
#
# class CharsForUTF32
@@ -60,27 +65,30 @@ module ActiveSupport #:nodoc:
end
end
- # Returns +true+ if _obj_ responds to the given method. Private methods are included in the search
- # only if the optional second parameter evaluates to +true+.
+ # Returns +true+ if _obj_ responds to the given method. Private methods
+ # are included in the search only if the optional second parameter
+ # evaluates to +true+.
def respond_to_missing?(method, include_private)
@wrapped_string.respond_to?(method, include_private)
end
- # Returns +true+ when the proxy class can handle the string. Returns +false+ otherwise.
+ # Returns +true+ when the proxy class can handle the string. Returns
+ # +false+ otherwise.
def self.consumes?(string)
string.encoding == Encoding::UTF_8
end
- # Works just like <tt>String#split</tt>, with the exception that the items in the resulting list are Chars
- # instances instead of String. This makes chaining methods easier.
+ # Works just like <tt>String#split</tt>, with the exception that the items
+ # in the resulting list are Chars instances instead of String. This makes
+ # chaining methods easier.
#
# 'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } # => ["CAF", " P", "RIFERÔL"]
def split(*args)
@wrapped_string.split(*args).map { |i| self.class.new(i) }
end
- # Works like like <tt>String#slice!</tt>, but returns an instance of Chars, or nil if the string was not
- # modified.
+ # Works like like <tt>String#slice!</tt>, but returns an instance of
+ # Chars, or nil if the string was not modified.
def slice!(*args)
chars(@wrapped_string.slice!(*args))
end
@@ -92,8 +100,9 @@ module ActiveSupport #:nodoc:
chars(Unicode.unpack_graphemes(@wrapped_string).reverse.flatten.pack('U*'))
end
- # Limits the byte size of the string to a number of bytes without breaking characters. Usable
- # when the storage for a string is limited for some reason.
+ # Limits the byte size of the string to a number of bytes without breaking
+ # characters. Usable when the storage for a string is limited for some
+ # reason.
#
# 'こんにちは'.mb_chars.limit(7).to_s # => "こん"
def limit(limit)
@@ -137,8 +146,9 @@ module ActiveSupport #:nodoc:
end
alias_method :titlecase, :titleize
- # Returns the KC normalization of the string by default. NFKC is considered the best normalization form for
- # passing strings to databases and validations.
+ # Returns the KC normalization of the string by default. NFKC is
+ # considered the best normalization form for passing strings to databases
+ # and validations.
#
# * <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
@@ -171,9 +181,11 @@ module ActiveSupport #:nodoc:
Unicode.unpack_graphemes(@wrapped_string).length
end
- # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string.
+ # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
+ # resulting in a valid UTF-8 string.
#
- # Passing +true+ will forcibly tidy all bytes, assuming that the string's encoding is entirely CP1252 or ISO-8859-1.
+ # Passing +true+ will forcibly tidy all bytes, assuming that the string's
+ # encoding is entirely CP1252 or ISO-8859-1.
def tidy_bytes(force = false)
chars(Unicode.tidy_bytes(@wrapped_string, force))
end
diff --git a/activesupport/lib/active_support/multibyte/unicode.rb b/activesupport/lib/active_support/multibyte/unicode.rb
index ef1711c60a..f49ca47f14 100644
--- a/activesupport/lib/active_support/multibyte/unicode.rb
+++ b/activesupport/lib/active_support/multibyte/unicode.rb
@@ -5,15 +5,17 @@ module ActiveSupport
extend self
- # A list of all available normalization forms. See http://www.unicode.org/reports/tr15/tr15-29.html for more
+ # A list of all available normalization forms.
+ # See http://www.unicode.org/reports/tr15/tr15-29.html for more
# information about normalization.
NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
# The Unicode version that is supported by the implementation
UNICODE_VERSION = '6.1.0'
- # The default normalization used for operations that require normalization. It can be set to any of the
- # normalizations in NORMALIZATION_FORMS.
+ # The default normalization used for operations that require
+ # normalization. It can be set to any of the normalizations
+ # in NORMALIZATION_FORMS.
#
# ActiveSupport::Multibyte::Unicode.default_normalization_form = :c
attr_accessor :default_normalization_form
@@ -49,19 +51,22 @@ module ActiveSupport
0x3000, # White_Space # Zs IDEOGRAPHIC SPACE
].flatten.freeze
- # BOM (byte order mark) can also be seen as whitespace, it's a non-rendering character used to distinguish
- # between little and big endian. This is not an issue in utf-8, so it must be ignored.
+ # BOM (byte order mark) can also be seen as whitespace, it's a
+ # non-rendering character used to distinguish between little and big
+ # endian. This is not an issue in utf-8, so it must be ignored.
LEADERS_AND_TRAILERS = WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM
- # Returns a regular expression pattern that matches the passed Unicode codepoints
+ # Returns a regular expression pattern that matches the passed Unicode
+ # codepoints.
def self.codepoints_to_pattern(array_of_codepoints) #:nodoc:
array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|')
end
TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u
LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u
- # Detect whether the codepoint is in a certain character class. Returns +true+ when it's in the specified
- # character class and +false+ otherwise. Valid character classes are: <tt>:cr</tt>, <tt>:lf</tt>, <tt>:l</tt>,
+ # Detect whether the codepoint is in a certain character class. Returns
+ # +true+ when it's in the specified character class and +false+ otherwise.
+ # Valid character classes are: <tt>:cr</tt>, <tt>:lf</tt>, <tt>:l</tt>,
# <tt>:v</tt>, <tt>:lv</tt>, <tt>:lvt</tt> and <tt>:t</tt>.
#
# Primarily used by the grapheme cluster support.
@@ -69,7 +74,8 @@ module ActiveSupport
classes.detect { |c| database.boundary[c] === codepoint } ? true : false
end
- # Unpack the string at grapheme boundaries. Returns a list of character lists.
+ # Unpack the string at grapheme boundaries. Returns a list of character
+ # lists.
#
# Unicode.unpack_graphemes('क्षि') # => [[2325, 2381], [2359], [2367]]
# Unicode.unpack_graphemes('Café') # => [[67], [97], [102], [233]]
@@ -206,9 +212,11 @@ module ActiveSupport
codepoints
end
- # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string.
+ # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
+ # resulting in a valid UTF-8 string.
#
- # Passing +true+ will forcibly tidy all bytes, assuming that the string's encoding is entirely CP1252 or ISO-8859-1.
+ # Passing +true+ will forcibly tidy all bytes, assuming that the string's
+ # encoding is entirely CP1252 or ISO-8859-1.
def tidy_bytes(string, force = false)
if force
return string.unpack("C*").map do |b|
@@ -257,13 +265,14 @@ module ActiveSupport
bytes.empty? ? "" : bytes.flatten.compact.pack("C*").unpack("U*").pack("U*")
end
- # Returns the KC normalization of the string by default. NFKC is considered the best normalization form for
- # passing strings to databases and validations.
+ # Returns the KC normalization of the string by default. NFKC is
+ # considered the best normalization form for passing strings to databases
+ # and validations.
#
# * <tt>string</tt> - The string to perform normalization on.
- # * <tt>form</tt> - The form you want to normalize in. Should be one of the following:
- # <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>. Default is
- # ActiveSupport::Multibyte.default_normalization_form
+ # * <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(string, form=nil)
form ||= @default_normalization_form
# See http://www.unicode.org/reports/tr15, Table 1
@@ -294,7 +303,7 @@ module ActiveSupport
apply_mapping string, :swapcase_mapping
end
- # Holds data about a codepoint in the Unicode database
+ # Holds data about a codepoint in the Unicode database.
class Codepoint
attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping
@@ -303,7 +312,7 @@ module ActiveSupport
end
end
- # Holds static data from the Unicode database
+ # Holds static data from the Unicode database.
class UnicodeDatabase
ATTRIBUTES = :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252
@@ -327,7 +336,8 @@ module ActiveSupport
EOS
end
- # Loads the Unicode database and returns all the internal objects of UnicodeDatabase.
+ # Loads the Unicode database and returns all the internal objects of
+ # UnicodeDatabase.
def load
begin
@codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
@@ -350,12 +360,12 @@ module ActiveSupport
end
end
- # Returns the directory in which the data files are stored
+ # Returns the directory in which the data files are stored.
def self.dirname
File.dirname(__FILE__) + '/../values/'
end
- # Returns the filename for the data file for this version
+ # Returns the filename for the data file for this version.
def self.filename
File.expand_path File.join(dirname, "unicode_tables.dat")
end
diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb
index b4657a8ba9..aefba1c4f5 100644
--- a/activesupport/lib/active_support/notifications.rb
+++ b/activesupport/lib/active_support/notifications.rb
@@ -4,19 +4,20 @@ require 'active_support/notifications/fanout'
module ActiveSupport
# = Notifications
#
- # <tt>ActiveSupport::Notifications</tt> provides an instrumentation API for Ruby.
+ # <tt>ActiveSupport::Notifications</tt> provides an instrumentation API for
+ # Ruby.
#
# == Instrumenters
#
# To instrument an event you just need to do:
#
- # ActiveSupport::Notifications.instrument("render", :extra => :information) do
- # render :text => "Foo"
+ # ActiveSupport::Notifications.instrument('render', extra: :information) do
+ # render text: 'Foo'
# end
#
# That executes the block first and notifies all subscribers once done.
#
- # In the example above "render" is the name of the event, and the rest is called
+ # In the example above +render+ is the name of the event, and the rest is called
# the _payload_. The payload is a mechanism that allows instrumenters to pass
# extra information to subscribers. Payloads consist of a hash whose contents
# are arbitrary and generally depend on the event.
@@ -28,21 +29,21 @@ module ActiveSupport
#
# events = []
#
- # ActiveSupport::Notifications.subscribe("render") do |*args|
+ # ActiveSupport::Notifications.subscribe('render') do |*args|
# events << ActiveSupport::Notifications::Event.new(*args)
# end
#
# That code returns right away, you are just subscribing to "render" events.
# The block is saved and will be called whenever someone instruments "render":
#
- # ActiveSupport::Notifications.instrument("render", :extra => :information) do
- # render :text => "Foo"
+ # ActiveSupport::Notifications.instrument('render', extra: :information) do
+ # render text: 'Foo'
# end
#
# event = events.first
# event.name # => "render"
# event.duration # => 10 (in milliseconds)
- # event.payload # => { :extra => :information }
+ # event.payload # => { extra: :information }
#
# The block in the <tt>subscribe</tt> call gets the name of the event, start
# timestamp, end timestamp, a string with a unique identifier for that event
@@ -63,7 +64,7 @@ module ActiveSupport
# module ActionController
# class PageRequest
# def call(name, started, finished, unique_id, payload)
- # Rails.logger.debug ["notification:", name, started, finished, unique_id, payload].join(" ")
+ # Rails.logger.debug ['notification:', name, started, finished, unique_id, payload].join(' ')
# end
# end
# end
diff --git a/activesupport/lib/active_support/notifications/instrumenter.rb b/activesupport/lib/active_support/notifications/instrumenter.rb
index 78d0397f1f..ab0b162ee0 100644
--- a/activesupport/lib/active_support/notifications/instrumenter.rb
+++ b/activesupport/lib/active_support/notifications/instrumenter.rb
@@ -13,7 +13,7 @@ module ActiveSupport
# Instrument the given block by measuring the time taken to execute it
# and publish it. Notice that events get sent even if an error occurs
- # in the passed-in block
+ # in the passed-in block.
def instrument(name, payload={})
@notifier.start(name, @id, payload)
begin
diff --git a/activesupport/lib/active_support/number_helper.rb b/activesupport/lib/active_support/number_helper.rb
index 3849f94a31..2191471daa 100644
--- a/activesupport/lib/active_support/number_helper.rb
+++ b/activesupport/lib/active_support/number_helper.rb
@@ -126,13 +126,13 @@ module ActiveSupport
# ==== Examples
#
# number_to_phone(5551234) # => 555-1234
- # number_to_phone("5551234") # => 555-1234
+ # number_to_phone('5551234') # => 555-1234
# number_to_phone(1235551234) # => 123-555-1234
# number_to_phone(1235551234, area_code: true) # => (123) 555-1234
# number_to_phone(1235551234, delimiter: ' ') # => 123 555 1234
# number_to_phone(1235551234, area_code: true, extension: 555) # => (123) 555-1234 x 555
# number_to_phone(1235551234, country_code: 1) # => +1-123-555-1234
- # number_to_phone("123a456") # => 123a456
+ # number_to_phone('123a456') # => 123a456
#
# number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: '.')
# # => +1.123.555.1234 x 1343
@@ -249,7 +249,7 @@ module ActiveSupport
# number_to_percentage(100, precision: 0) # => 100%
# number_to_percentage(1000, delimiter: '.', separator: ,') # => 1.000,000%
# number_to_percentage(302.24398923423, precision: 5) # => 302.24399%
- # number_to_percentage(1000, :locale => :fr) # => 1 000,000%
+ # number_to_percentage(1000, locale: :fr) # => 1 000,000%
# number_to_percentage('98a') # => 98a%
# number_to_percentage(100, format: '%n %') # => 100 %
def number_to_percentage(number, options = {})
@@ -524,7 +524,7 @@ module ActiveSupport
# ==== Custom Unit Quantifiers
#
# You can also use your own custom unit quantifiers:
- # number_to_human(500000, :units => {:unit => "ml", :thousand => "lt"}) # => "500 lt"
+ # number_to_human(500000, units: { unit: 'ml', thousand: 'lt' }) # => "500 lt"
#
# If in your I18n locale you have:
#
@@ -542,12 +542,12 @@ module ActiveSupport
#
# Then you could do:
#
- # number_to_human(543934, :units => :distance) # => "544 kilometers"
- # number_to_human(54393498, :units => :distance) # => "54400 kilometers"
- # number_to_human(54393498000, :units => :distance) # => "54.4 gazillion-distance"
- # number_to_human(343, :units => :distance, :precision => 1) # => "300 meters"
- # number_to_human(1, :units => :distance) # => "1 meter"
- # number_to_human(0.34, :units => :distance) # => "34 centimeters"
+ # number_to_human(543934, units: :distance) # => "544 kilometers"
+ # number_to_human(54393498, units: :distance) # => "54400 kilometers"
+ # number_to_human(54393498000, units: :distance) # => "54.4 gazillion-distance"
+ # number_to_human(343, units: :distance, precision: 1) # => "300 meters"
+ # number_to_human(1, units: :distance) # => "1 meter"
+ # number_to_human(0.34, units: :distance) # => "34 centimeters"
def number_to_human(number, options = {})
options = options.symbolize_keys
diff --git a/activesupport/lib/active_support/ordered_options.rb b/activesupport/lib/active_support/ordered_options.rb
index 60e6cd55ad..c9518bda79 100644
--- a/activesupport/lib/active_support/ordered_options.rb
+++ b/activesupport/lib/active_support/ordered_options.rb
@@ -1,20 +1,19 @@
-# Usually key value pairs are handled something like this:
-#
-# h = {}
-# h[:boy] = 'John'
-# h[:girl] = 'Mary'
-# h[:boy] # => 'John'
-# h[:girl] # => 'Mary'
-#
-# Using <tt>OrderedOptions</tt>, the above code could be reduced to:
-#
-# h = ActiveSupport::OrderedOptions.new
-# h.boy = 'John'
-# h.girl = 'Mary'
-# h.boy # => 'John'
-# h.girl # => 'Mary'
-#
-module ActiveSupport #:nodoc:
+module ActiveSupport
+ # Usually key value pairs are handled something like this:
+ #
+ # h = {}
+ # h[:boy] = 'John'
+ # h[:girl] = 'Mary'
+ # h[:boy] # => 'John'
+ # h[:girl] # => 'Mary'
+ #
+ # Using +OrderedOptions+, the above code could be reduced to:
+ #
+ # h = ActiveSupport::OrderedOptions.new
+ # h.boy = 'John'
+ # h.girl = 'Mary'
+ # h.boy # => 'John'
+ # h.girl # => 'Mary'
class OrderedOptions < Hash
alias_method :_get, :[] # preserve the original #[] method
protected :_get # make it protected
diff --git a/activesupport/lib/active_support/queueing.rb b/activesupport/lib/active_support/queueing.rb
new file mode 100644
index 0000000000..7c352886f3
--- /dev/null
+++ b/activesupport/lib/active_support/queueing.rb
@@ -0,0 +1,133 @@
+require 'delegate'
+require 'thread'
+
+module ActiveSupport
+ # A Queue that simply inherits from STDLIB's Queue. When this
+ # queue is used, Rails automatically starts a job runner in a
+ # background thread.
+ class Queue < ::Queue
+ attr_writer :consumer
+
+ def initialize(consumer_options = {})
+ super()
+ @consumer_options = consumer_options
+ end
+
+ def consumer
+ @consumer ||= ThreadedQueueConsumer.new(self, @consumer_options)
+ end
+
+ # Drain the queue, running all jobs in a different thread. This method
+ # may not be available on production queues.
+ def drain
+ # run the jobs in a separate thread so assumptions of synchronous
+ # jobs are caught in test mode.
+ consumer.drain
+ end
+ end
+
+ class SynchronousQueue < Queue
+ def push(job)
+ super.tap { drain }
+ end
+ alias << push
+ alias enq push
+ end
+
+ # In test mode, the Rails queue is backed by an Array so that assertions
+ # can be made about its contents. The test queue provides a +jobs+
+ # method to make assertions about the queue's contents and a +drain+
+ # method to drain the queue and run the jobs.
+ #
+ # Jobs are run in a separate thread to catch mistakes where code
+ # assumes that the job is run in the same thread.
+ class TestQueue < Queue
+ # Get a list of the jobs off this queue. This method may not be
+ # available on production queues.
+ def jobs
+ @que.dup
+ end
+
+ # Marshal and unmarshal job before pushing it onto the queue. This will
+ # raise an exception on any attempts in tests to push jobs that can't (or
+ # shouldn't) be marshalled.
+ def push(job)
+ super Marshal.load(Marshal.dump(job))
+ end
+ end
+
+ # A container for multiple queues. This class delegates to a default Queue
+ # so that <tt>Rails.queue.push</tt> and friends will Just Work. To use this class
+ # with multiple queues:
+ #
+ # # In your configuration:
+ # Rails.queue[:image_queue] = SomeQueue.new
+ # Rails.queue[:mail_queue] = SomeQueue.new
+ #
+ # # In your app code:
+ # Rails.queue[:mail_queue].push SomeJob.new
+ #
+ class QueueContainer < DelegateClass(::Queue)
+ def initialize(default_queue)
+ @queues = { :default => default_queue }
+ super(default_queue)
+ end
+
+ def [](queue_name)
+ @queues[queue_name]
+ end
+
+ def []=(queue_name, queue)
+ @queues[queue_name] = queue
+ end
+ end
+
+ # The threaded consumer will run jobs in a background thread in
+ # development mode or in a VM where running jobs on a thread in
+ # production mode makes sense.
+ #
+ # When the process exits, the consumer pushes a nil onto the
+ # queue and joins the thread, which will ensure that all jobs
+ # are executed before the process finally dies.
+ class ThreadedQueueConsumer
+ def self.start(*args)
+ new(*args).start
+ end
+
+ def initialize(queue, options = {})
+ @queue = queue
+ @logger = options[:logger]
+ end
+
+ def start
+ @thread = Thread.new { consume }
+ self
+ end
+
+ def shutdown
+ @queue.push nil
+ @thread.join
+ end
+
+ def drain
+ run(@queue.pop) until @queue.empty?
+ end
+
+ def consume
+ while job = @queue.pop
+ run job
+ end
+ end
+
+ def run(job)
+ job.run
+ rescue Exception => exception
+ handle_exception job, exception
+ end
+
+ def handle_exception(job, exception)
+ raise exception unless @logger
+ @logger.error "Job Error: #{exception.message}\n#{exception.backtrace.join("\n")}"
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/railtie.rb b/activesupport/lib/active_support/railtie.rb
index 30ac881090..133aa6a054 100644
--- a/activesupport/lib/active_support/railtie.rb
+++ b/activesupport/lib/active_support/railtie.rb
@@ -2,9 +2,11 @@ require "active_support"
require "active_support/i18n_railtie"
module ActiveSupport
- class Railtie < Rails::Railtie
+ class Railtie < Rails::Railtie # :nodoc:
config.active_support = ActiveSupport::OrderedOptions.new
+ config.eager_load_namespaces << ActiveSupport
+
initializer "active_support.deprecation_behavior" do |app|
if deprecation = app.config.active_support.deprecation
ActiveSupport::Deprecation.behavior = deprecation
@@ -25,6 +27,15 @@ module ActiveSupport
Time.zone_default = zone_default
end
+ # Sets the default week start
+ # If assigned value is not a valid day symbol (e.g. :sunday, :monday, ...), an exception will be raised.
+ initializer "active_support.initialize_beginning_of_week" do |app|
+ require 'active_support/core_ext/date/calculations'
+ beginning_of_week_default = Date.find_beginning_of_week!(app.config.beginning_of_week)
+
+ Date.beginning_of_week_default = beginning_of_week_default
+ end
+
initializer "active_support.set_configs" do |app|
app.config.active_support.each do |k, v|
k = "#{k}="
diff --git a/activesupport/lib/active_support/rescuable.rb b/activesupport/lib/active_support/rescuable.rb
index 7aecdd11d3..9a038dfbca 100644
--- a/activesupport/lib/active_support/rescuable.rb
+++ b/activesupport/lib/active_support/rescuable.rb
@@ -31,11 +31,11 @@ module ActiveSupport
# any.
#
# class ApplicationController < ActionController::Base
- # rescue_from User::NotAuthorized, :with => :deny_access # self defined exception
- # rescue_from ActiveRecord::RecordInvalid, :with => :show_errors
+ # rescue_from User::NotAuthorized, with: :deny_access # self defined exception
+ # rescue_from ActiveRecord::RecordInvalid, with: :show_errors
#
# rescue_from 'MyAppError::Base' do |exception|
- # render :xml => exception, :status => 500
+ # render xml: exception, status: 500
# end
#
# protected
diff --git a/activesupport/lib/active_support/string_inquirer.rb b/activesupport/lib/active_support/string_inquirer.rb
index 5f20bfa7bc..45271c9163 100644
--- a/activesupport/lib/active_support/string_inquirer.rb
+++ b/activesupport/lib/active_support/string_inquirer.rb
@@ -3,12 +3,11 @@ module ActiveSupport
# for equality. The value returned by <tt>Rails.env</tt> is wrapped
# in a StringInquirer object so instead of calling this:
#
- # Rails.env == "production"
+ # Rails.env == 'production'
#
# you can call this:
#
# Rails.env.production?
- #
class StringInquirer < String
private
diff --git a/activesupport/lib/active_support/tagged_logging.rb b/activesupport/lib/active_support/tagged_logging.rb
index 9cd8ac36bc..33810442da 100644
--- a/activesupport/lib/active_support/tagged_logging.rb
+++ b/activesupport/lib/active_support/tagged_logging.rb
@@ -6,20 +6,38 @@ module ActiveSupport
# Wraps any standard Logger object to provide tagging capabilities.
#
# logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
- # logger.tagged("BCX") { logger.info "Stuff" } # Logs "[BCX] Stuff"
- # logger.tagged("BCX", "Jason") { logger.info "Stuff" } # Logs "[BCX] [Jason] Stuff"
- # logger.tagged("BCX") { logger.tagged("Jason") { logger.info "Stuff" } } # Logs "[BCX] [Jason] Stuff"
+ # logger.tagged('BCX') { logger.info 'Stuff' } # Logs "[BCX] Stuff"
+ # logger.tagged('BCX', "Jason") { logger.info 'Stuff' } # Logs "[BCX] [Jason] Stuff"
+ # logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } } # Logs "[BCX] [Jason] Stuff"
#
- # This is used by the default Rails.logger as configured by Railties to make it easy to stamp log lines
- # with subdomains, request ids, and anything else to aid debugging of multi-user production applications.
+ # This is used by the default Rails.logger as configured by Railties to make
+ # it easy to stamp log lines with subdomains, request ids, and anything else
+ # to aid debugging of multi-user production applications.
module TaggedLogging
module Formatter # :nodoc:
- # This method is invoked when a log event occurs
+ # This method is invoked when a log event occurs.
def call(severity, timestamp, progname, msg)
- super(severity, timestamp, progname, "#{tags_text} #{msg}".lstrip)
+ super(severity, timestamp, progname, "#{tags_text}#{msg}")
end
- def clear!
+ def tagged(*tags)
+ new_tags = push_tags(*tags)
+ yield self
+ ensure
+ pop_tags(new_tags.size)
+ end
+
+ def push_tags(*tags)
+ tags.flatten.reject(&:blank?).tap do |new_tags|
+ current_tags.concat new_tags
+ end
+ end
+
+ def pop_tags(size = 1)
+ current_tags.pop size
+ end
+
+ def clear_tags!
current_tags.clear
end
@@ -28,30 +46,29 @@ module ActiveSupport
end
private
- def tags_text
- tags = current_tags
- if tags.any?
- tags.collect { |tag| "[#{tag}]" }.join(' ')
+ def tags_text
+ tags = current_tags
+ if tags.any?
+ tags.collect { |tag| "[#{tag}] " }.join
+ end
end
- end
end
def self.new(logger)
+ # Ensure we set a default formatter so we aren't extending nil!
+ logger.formatter ||= ActiveSupport::Logger::SimpleFormatter.new
logger.formatter.extend Formatter
logger.extend(self)
end
- def tagged(*new_tags)
- tags = formatter.current_tags
- new_tags = new_tags.flatten.reject(&:blank?)
- tags.concat new_tags
- yield self
- ensure
- tags.pop(new_tags.size)
+ delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter
+
+ def tagged(*tags)
+ formatter.tagged(*tags) { yield self }
end
def flush
- formatter.clear!
+ clear_tags!
super if defined?(super)
end
end
diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb
index d2b8e602f9..7b9378a7f6 100644
--- a/activesupport/lib/active_support/test_case.rb
+++ b/activesupport/lib/active_support/test_case.rb
@@ -1,10 +1,12 @@
gem 'minitest' # make sure we get the gem, not stdlib
require 'minitest/spec'
+require 'active_support/testing/tagged_logging'
require 'active_support/testing/setup_and_teardown'
require 'active_support/testing/assertions'
require 'active_support/testing/deprecation'
require 'active_support/testing/isolation'
require 'active_support/testing/mocha_module'
+require 'active_support/testing/constant_lookup'
require 'active_support/core_ext/kernel/reporting'
require 'active_support/deprecation'
@@ -32,6 +34,7 @@ module ActiveSupport
:sorted
end
+ include ActiveSupport::Testing::TaggedLogging
include ActiveSupport::Testing::SetupAndTeardown
include ActiveSupport::Testing::Assertions
include ActiveSupport::Testing::Deprecation
diff --git a/activesupport/lib/active_support/testing/assertions.rb b/activesupport/lib/active_support/testing/assertions.rb
index ee1a647ed8..8466049e20 100644
--- a/activesupport/lib/active_support/testing/assertions.rb
+++ b/activesupport/lib/active_support/testing/assertions.rb
@@ -31,7 +31,7 @@ module ActiveSupport
#
# A lambda or a list of lambdas can be passed in and evaluated:
#
- # assert_difference lambda { Article.count }, 2 do
+ # assert_difference ->{ Article.count }, 2 do
# post :create, article: {...}
# end
#
@@ -77,7 +77,8 @@ module ActiveSupport
assert_difference expression, 0, message, &block
end
- # Test if an expression is blank. Passes if <tt>object.blank?</tt> is +true+.
+ # Test if an expression is blank. Passes if <tt>object.blank?</tt>
+ # is +true+.
#
# assert_blank [] # => true
# assert_blank [[]] # => [[]] is not blank
@@ -90,7 +91,8 @@ module ActiveSupport
assert object.blank?, message
end
- # Test if an expression is not blank. Passes if <tt>object.present?</tt> is +true+.
+ # Test if an expression is not blank. Passes if <tt>object.present?</tt>
+ # is +true+.
#
# assert_present({ data: 'x' }) # => true
# assert_present({}) # => {} is blank
diff --git a/activesupport/lib/active_support/testing/constant_lookup.rb b/activesupport/lib/active_support/testing/constant_lookup.rb
new file mode 100644
index 0000000000..73e87befb6
--- /dev/null
+++ b/activesupport/lib/active_support/testing/constant_lookup.rb
@@ -0,0 +1,52 @@
+require "active_support/concern"
+require "active_support/inflector"
+
+module ActiveSupport
+ module Testing
+ # Resolves a constant from a minitest spec name.
+ #
+ # Given the following spec-style test:
+ #
+ # describe WidgetsController, :index do
+ # describe "authenticated user" do
+ # describe "returns widgets" do
+ # it "has a controller that exists" do
+ # assert_kind_of WidgetsController, @controller
+ # end
+ # end
+ # end
+ # end
+ #
+ # The test will have the following name:
+ #
+ # "WidgetsController::index::authenticated user::returns widgets"
+ #
+ # The constant WidgetsController can be resolved from the name.
+ # The following code will resolve the constant:
+ #
+ # controller = determine_constant_from_test_name(name) do |constant|
+ # Class === constant && constant < ::ActionController::Metal
+ # end
+ module ConstantLookup
+ extend ::ActiveSupport::Concern
+
+ module ClassMethods
+ def determine_constant_from_test_name(test_name)
+ names = test_name.split "::"
+ while names.size > 0 do
+ names.last.sub!(/Test$/, "")
+ begin
+ constant = names.join("::").constantize
+ break(constant) if yield(constant)
+ rescue NameError
+ # Constant wasn't found, move on
+ ensure
+ names.pop
+ end
+ end
+ end
+ end
+
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb
index a6c57cd0ff..7102ffe2ed 100644
--- a/activesupport/lib/active_support/testing/performance.rb
+++ b/activesupport/lib/active_support/testing/performance.rb
@@ -70,7 +70,7 @@ module ActiveSupport
end
protected
- # overridden by each implementation
+ # overridden by each implementation.
def run_gc; end
def run_warmup
@@ -114,7 +114,7 @@ module ActiveSupport
end
end
- # overridden by each implementation
+ # overridden by each implementation.
class Profiler < Performer
def time_with_block
before = Time.now
@@ -221,11 +221,11 @@ module ActiveSupport
end
end
- # overridden by each implementation
+ # overridden by each implementation.
def profile; end
protected
- # overridden by each implementation
+ # overridden by each implementation.
def with_gc_stats; end
end
diff --git a/activesupport/lib/active_support/testing/tagged_logging.rb b/activesupport/lib/active_support/testing/tagged_logging.rb
new file mode 100644
index 0000000000..899467c45f
--- /dev/null
+++ b/activesupport/lib/active_support/testing/tagged_logging.rb
@@ -0,0 +1,30 @@
+require 'active_support/concern'
+
+module ActiveSupport
+ module Testing
+ module TaggedLogging
+ extend ActiveSupport::Concern
+
+ attr_writer :tagged_logger
+
+ def before_setup
+ tagged_logger.push_tags(self.class.name, __name__) if tagged_logging?
+ super
+ end
+
+ def after_teardown
+ super
+ tagged_logger.pop_tags(2) if tagged_logging?
+ end
+
+ private
+ def tagged_logger
+ @tagged_logger ||= (defined?(Rails.logger) && Rails.logger)
+ end
+
+ def tagged_logging?
+ tagged_logger && tagged_logger.respond_to?(:push_tags)
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index 93c2d614f5..b931de3fac 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -2,11 +2,13 @@ require 'active_support/values/time_zone'
require 'active_support/core_ext/object/acts_like'
module ActiveSupport
- # A Time-like class that can represent a time in any time zone. Necessary because standard Ruby Time instances are
- # limited to UTC and the system's <tt>ENV['TZ']</tt> zone.
+ # A Time-like class that can represent a time in any time zone. Necessary
+ # because standard Ruby Time instances are limited to UTC and the
+ # system's <tt>ENV['TZ']</tt> zone.
#
- # You shouldn't ever need to create a TimeWithZone instance directly via <tt>new</tt> . Instead use methods
- # +local+, +parse+, +at+ and +now+ on TimeZone instances, and +in_time_zone+ on Time and DateTime instances.
+ # You shouldn't ever need to create a TimeWithZone instance directly via +new+.
+ # Instead use methods +local+, +parse+, +at+ and +now+ on TimeZone instances,
+ # and +in_time_zone+ on Time and DateTime instances.
#
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
# Time.zone.local(2007, 2, 10, 15, 30, 45) # => Sat, 10 Feb 2007 15:30:45 EST -05:00
@@ -17,7 +19,8 @@ module ActiveSupport
#
# See Time and TimeZone for further documentation of these methods.
#
- # TimeWithZone instances implement the same API as Ruby Time instances, so that Time and TimeWithZone instances are interchangeable.
+ # TimeWithZone instances implement the same API as Ruby Time instances, so
+ # that Time and TimeWithZone instances are interchangeable.
#
# t = Time.zone.now # => Sun, 18 May 2008 13:27:25 EDT -04:00
# t.hour # => 13
@@ -30,10 +33,9 @@ module ActiveSupport
# t > Time.utc(1999) # => true
# t.is_a?(Time) # => true
# t.is_a?(ActiveSupport::TimeWithZone) # => true
- #
class TimeWithZone
- # Report class name as 'Time' to thwart type checking
+ # Report class name as 'Time' to thwart type checking.
def self.name
'Time'
end
@@ -71,7 +73,8 @@ module ActiveSupport
utc.in_time_zone(new_zone)
end
- # Returns a <tt>Time.local()</tt> instance of the simultaneous time in your system's <tt>ENV['TZ']</tt> zone
+ # Returns a <tt>Time.local()</tt> instance of the simultaneous time in your
+ # system's <tt>ENV['TZ']</tt> zone.
def localtime
utc.respond_to?(:getlocal) ? utc.getlocal : utc.to_time.getlocal
end
@@ -97,7 +100,8 @@ module ActiveSupport
utc? && alternate_utc_string || TimeZone.seconds_to_utc_offset(utc_offset, colon)
end
- # Time uses +zone+ to display the time zone abbreviation, so we're duck-typing it.
+ # Time uses +zone+ to display the time zone abbreviation, so we're
+ # duck-typing it.
def zone
period.zone_identifier.to_s
end
@@ -115,9 +119,10 @@ module ActiveSupport
end
alias_method :iso8601, :xmlschema
- # Coerces time to a string for JSON encoding. The default format is ISO 8601. You can get
- # %Y/%m/%d %H:%M:%S +offset style by setting <tt>ActiveSupport::JSON::Encoding.use_standard_json_time_format</tt>
- # to false.
+ # Coerces time to a string for JSON encoding. The default format is ISO 8601.
+ # You can get %Y/%m/%d %H:%M:%S +offset style by setting
+ # <tt>ActiveSupport::JSON::Encoding.use_standard_json_time_format</tt>
+ # to +false+.
#
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
# Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
@@ -126,7 +131,6 @@ module ActiveSupport
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
# Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
# # => "2005/02/01 15:15:10 +0000"
- #
def as_json(options = nil)
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
xmlschema
@@ -165,10 +169,14 @@ module ActiveSupport
end
alias_method :to_formatted_s, :to_s
- # 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
+ # 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))
+ format = format.gsub('%Z', zone)
+ .gsub('%z', formatted_offset(false))
+ .gsub('%:z', formatted_offset(true))
+ .gsub('%::z', formatted_offset(true) + ":00")
time.strftime(format)
end
@@ -307,14 +315,16 @@ module ActiveSupport
initialize(variables[0].utc, ::Time.find_zone(variables[1]), variables[2].utc)
end
- # Ensure proxy class responds to all methods that underlying time instance responds to.
+ # Ensure proxy class responds to all methods that underlying time instance
+ # responds to.
def respond_to_missing?(sym, include_priv)
# consistently respond false to acts_like?(:date), regardless of whether #time is a Time or DateTime
return false if sym.to_sym == :acts_like_date?
time.respond_to?(sym, include_priv)
end
- # Send the missing method to +time+ instance, and wrap result in a new TimeWithZone with the existing +time_zone+.
+ # Send the missing method to +time+ instance, and wrap result in a new
+ # TimeWithZone with the existing +time_zone+.
def method_missing(sym, *args, &block)
wrap_with_time_zone time.__send__(sym, *args, &block)
end
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index cc3e6a4bf3..231d61da96 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -2,29 +2,36 @@ require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/try'
module ActiveSupport
- # The TimeZone class serves as a wrapper around TZInfo::Timezone instances. It allows us to do the following:
+ # The TimeZone class serves as a wrapper around TZInfo::Timezone instances.
+ # It allows us to do the following:
#
- # * Limit the set of zones provided by TZInfo to a meaningful subset of 142 zones.
- # * Retrieve and display zones with a friendlier name (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
+ # * Limit the set of zones provided by TZInfo to a meaningful subset of 142
+ # zones.
+ # * Retrieve and display zones with a friendlier name
+ # (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
# * Lazily load TZInfo::Timezone instances only when they're needed.
- # * Create ActiveSupport::TimeWithZone instances via TimeZone's +local+, +parse+, +at+ and +now+ methods.
+ # * Create ActiveSupport::TimeWithZone instances via TimeZone's +local+,
+ # +parse+, +at+ and +now+ methods.
#
- # If you set <tt>config.time_zone</tt> in the Rails Application, you can access this TimeZone object via <tt>Time.zone</tt>:
+ # If you set <tt>config.time_zone</tt> in the Rails Application, you can
+ # access this TimeZone object via <tt>Time.zone</tt>:
#
# # application.rb:
# class Application < Rails::Application
- # config.time_zone = "Eastern Time (US & Canada)"
+ # config.time_zone = 'Eastern Time (US & Canada)'
# end
#
- # Time.zone # => #<TimeZone:0x514834...>
- # Time.zone.name # => "Eastern Time (US & Canada)"
- # Time.zone.now # => Sun, 18 May 2008 14:30:44 EDT -04:00
+ # Time.zone # => #<TimeZone:0x514834...>
+ # Time.zone.name # => "Eastern Time (US & Canada)"
+ # Time.zone.now # => Sun, 18 May 2008 14:30:44 EDT -04:00
#
- # The version of TZInfo bundled with Active Support only includes the definitions necessary to support the zones
- # defined by the TimeZone class. If you need to use zones that aren't defined by TimeZone, you'll need to install the TZInfo gem
- # (if a recent version of the gem is installed locally, this will be used instead of the bundled version.)
+ # The version of TZInfo bundled with Active Support only includes the
+ # definitions necessary to support the zones defined by the TimeZone class.
+ # If you need to use zones that aren't defined by TimeZone, you'll need to
+ # install the TZInfo gem (if a recent version of the gem is installed locally,
+ # this will be used instead of the bundled version.)
class TimeZone
- # Keys are Rails TimeZone names, values are TZInfo identifiers
+ # Keys are Rails TimeZone names, values are TZInfo identifiers.
MAPPING = {
"International Date Line West" => "Pacific/Midway",
"Midway Island" => "Pacific/Midway",
@@ -175,8 +182,8 @@ module ActiveSupport
UTC_OFFSET_WITH_COLON = '%s%02d:%02d'
UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.sub(':', '')
- # Assumes self represents an offset from UTC in seconds (as returned from Time#utc_offset)
- # and turns this into an +HH:MM formatted string.
+ # Assumes self represents an offset from UTC in seconds (as returned from
+ # Time#utc_offset) and turns this into an +HH:MM formatted string.
#
# TimeZone.seconds_to_utc_offset(-21_600) # => "-06:00"
def self.seconds_to_utc_offset(seconds, colon = true)
@@ -193,8 +200,8 @@ module ActiveSupport
# Create a new TimeZone object with the given name and offset. The
# offset is the number of seconds that this time zone is offset from UTC
- # (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).
+ # (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)
self.class.send(:require_tzinfo)
@@ -228,7 +235,7 @@ module ActiveSupport
result
end
- # Compare #name and TZInfo identifier to a supplied regexp, returning true
+ # Compare #name and TZInfo identifier to a supplied regexp, returning +true+
# if a match is found.
def =~(re)
return true if name =~ re || MAPPING[name] =~ re
@@ -239,33 +246,37 @@ module ActiveSupport
"(GMT#{formatted_offset}) #{name}"
end
- # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from given values.
+ # Method for creating new ActiveSupport::TimeWithZone instance in time zone
+ # of +self+ from given values.
#
- # Time.zone = "Hawaii" # => "Hawaii"
- # Time.zone.local(2007, 2, 1, 15, 30, 45) # => Thu, 01 Feb 2007 15:30:45 HST -10:00
+ # Time.zone = 'Hawaii' # => "Hawaii"
+ # Time.zone.local(2007, 2, 1, 15, 30, 45) # => Thu, 01 Feb 2007 15:30:45 HST -10:00
def local(*args)
time = Time.utc_time(*args)
ActiveSupport::TimeWithZone.new(nil, self, time)
end
- # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from number of seconds since the Unix epoch.
+ # Method for creating new ActiveSupport::TimeWithZone instance in time zone
+ # of +self+ from number of seconds since the Unix epoch.
#
- # Time.zone = "Hawaii" # => "Hawaii"
+ # Time.zone = 'Hawaii' # => "Hawaii"
# Time.utc(2000).to_f # => 946684800.0
# Time.zone.at(946684800.0) # => Fri, 31 Dec 1999 14:00:00 HST -10:00
def at(secs)
Time.at(secs).utc.in_time_zone(self)
end
- # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from parsed string.
+ # Method for creating new ActiveSupport::TimeWithZone instance in time zone
+ # of +self+ from parsed string.
#
- # Time.zone = "Hawaii" # => "Hawaii"
- # Time.zone.parse('1999-12-31 14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+ # Time.zone = 'Hawaii' # => "Hawaii"
+ # Time.zone.parse('1999-12-31 14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
#
- # If upper components are missing from the string, they are supplied from TimeZone#now:
+ # If upper components are missing from the string, they are supplied from
+ # TimeZone#now:
#
- # 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
+ # 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?
@@ -282,8 +293,8 @@ module ActiveSupport
end
end
- # Returns an ActiveSupport::TimeWithZone instance representing the current time
- # in the time zone represented by +self+.
+ # Returns an ActiveSupport::TimeWithZone instance representing the current
+ # time in the time zone represented by +self+.
#
# Time.zone = 'Hawaii' # => "Hawaii"
# Time.zone.now # => Wed, 23 Jan 2008 20:24:27 HST -10:00
@@ -296,23 +307,27 @@ module ActiveSupport
tzinfo.now.to_date
end
- # 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.
+ # 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.
+ # 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)
end
- # Available so that TimeZone instances respond like TZInfo::Timezone instances
+ # Available so that TimeZone instances respond like TZInfo::Timezone
+ # instances.
def period_for_utc(time)
tzinfo.period_for_utc(time)
end
- # Available so that TimeZone instances respond like TZInfo::Timezone instances
+ # Available so that TimeZone instances respond like TZInfo::Timezone
+ # instances.
def period_for_local(time, dst=true)
tzinfo.period_for_local(time, dst)
end
diff --git a/activesupport/lib/active_support/xml_mini/libxml.rb b/activesupport/lib/active_support/xml_mini/libxml.rb
index 26556598fd..47a2824186 100644
--- a/activesupport/lib/active_support/xml_mini/libxml.rb
+++ b/activesupport/lib/active_support/xml_mini/libxml.rb
@@ -37,7 +37,7 @@ module LibXML #:nodoc:
module Node #:nodoc:
CONTENT_ROOT = '__content__'.freeze
- # Convert XML document to hash
+ # Convert XML document to hash.
#
# hash::
# Hash to merge the converted element into.
diff --git a/activesupport/lib/active_support/xml_mini/nokogiri.rb b/activesupport/lib/active_support/xml_mini/nokogiri.rb
index bb0a52bdcf..7398d4fa82 100644
--- a/activesupport/lib/active_support/xml_mini/nokogiri.rb
+++ b/activesupport/lib/active_support/xml_mini/nokogiri.rb
@@ -40,7 +40,7 @@ module ActiveSupport
module Node #:nodoc:
CONTENT_ROOT = '__content__'.freeze
- # Convert XML document to hash
+ # Convert XML document to hash.
#
# hash::
# Hash to merge the converted element into.
diff --git a/activesupport/lib/active_support/xml_mini/rexml.rb b/activesupport/lib/active_support/xml_mini/rexml.rb
index a2a87337a6..5c7c78bf70 100644
--- a/activesupport/lib/active_support/xml_mini/rexml.rb
+++ b/activesupport/lib/active_support/xml_mini/rexml.rb
@@ -8,7 +8,7 @@ module ActiveSupport
CONTENT_KEY = '__content__'.freeze
- # Parse an XML Document string or IO into a simple hash
+ # Parse an XML Document string or IO into a simple hash.
#
# Same as XmlSimple::xml_in but doesn't shoot itself in the foot,
# and uses the defaults from Active Support.