update AS docs [ci skip]
This commit is contained in:
parent
c1c9f1c7b9
commit
d71d5ba71f
|
@ -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
|
||||
|
|
|
@ -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,7 +47,6 @@ module ActiveSupport
|
|||
end
|
||||
|
||||
# Silence the logger during the execution of the block.
|
||||
#
|
||||
def silence
|
||||
old_logger_level, logger.level = logger.level, ::Logger::ERROR if logger
|
||||
yield
|
||||
|
|
|
@ -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
|
||||
# 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.
|
||||
# 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.
|
||||
# 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
|
||||
|
|
|
@ -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.
|
||||
|
@ -294,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
|
||||
|
||||
|
@ -351,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 : {}
|
||||
|
@ -367,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, &block| stuff; result = block.call; 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
|
||||
|
@ -376,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
|
||||
|
||||
|
@ -417,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|
|
||||
|
@ -463,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)
|
||||
|
@ -505,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)
|
||||
|
|
|
@ -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'
|
||||
#
|
||||
|
|
|
@ -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,7 @@ module ActiveSupport
|
|||
# User.allowed_access # => false
|
||||
#
|
||||
# User.new.allowed_access = true # => NoMethodError
|
||||
# User.new.allowed_access # => NoMethodError
|
||||
# User.new.allowed_access # => NoMethodError
|
||||
def config_accessor(*names)
|
||||
options = names.extract_options!
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -182,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)) }
|
||||
|
@ -223,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
|
||||
|
@ -337,8 +342,9 @@ 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 = $` if path =~ /\.rb\z/
|
||||
expanded_path = File.expand_path(path)
|
||||
|
@ -371,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)
|
||||
|
@ -385,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
|
||||
|
@ -402,8 +409,8 @@ 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
|
||||
|
@ -421,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
|
||||
|
||||
|
@ -558,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,11 +16,11 @@ 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)
|
||||
#
|
||||
# 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"]
|
||||
#
|
||||
|
@ -39,7 +40,7 @@ module ActiveSupport
|
|||
#
|
||||
# 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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] = [] }
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -4,7 +4,8 @@ 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
|
||||
#
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module ActiveSupport #:nodoc:
|
||||
module ActiveSupport
|
||||
# Usually key value pairs are handled something like this:
|
||||
#
|
||||
# h = {}
|
||||
|
@ -7,7 +7,7 @@ module ActiveSupport #:nodoc:
|
|||
# h[:boy] # => 'John'
|
||||
# h[:girl] # => 'Mary'
|
||||
#
|
||||
# Using <tt>OrderedOptions</tt>, the above code could be reduced to:
|
||||
# Using +OrderedOptions+, the above code could be reduced to:
|
||||
#
|
||||
# h = ActiveSupport::OrderedOptions.new
|
||||
# h.boy = 'John'
|
||||
|
|
|
@ -2,7 +2,7 @@ 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -6,15 +6,16 @@ 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}")
|
||||
end
|
||||
|
|
|
@ -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,8 +169,9 @@ 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))
|
||||
time.strftime(format)
|
||||
|
@ -307,14 +312,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
|
||||
|
|
Loading…
Reference in New Issue