aboutsummaryrefslogtreecommitdiffstats
path: root/railties/guides/source/active_support_core_extensions.textile
diff options
context:
space:
mode:
Diffstat (limited to 'railties/guides/source/active_support_core_extensions.textile')
-rw-r--r--railties/guides/source/active_support_core_extensions.textile290
1 files changed, 169 insertions, 121 deletions
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index 54f766fffd..788f528654 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -1,8 +1,10 @@
h2. Active Support Core Extensions
-Active Support is the Rails component responsible for providing Ruby language extensions, utilities, and other transversal stuff. It offers a richer bottom-line at the language level, targeted both at the development of Rails applications, and at the development of Rails itself.
+Active Support is the Ruby on Rails component responsible for providing Ruby language extensions, utilities, and other transversal stuff.
-By referring to this guide you will learn the extensions to the Ruby core classes and modules provided by Rails.
+It offers a richer bottom-line at the language level, targeted both at the development of Rails applications, and at the development of Ruby on Rails itself.
+
+By referring to this guide you will learn the extensions to the Ruby core classes and modules provided by Active Support.
endprologue.
@@ -18,7 +20,7 @@ Thus, after a simple require like:
require 'active_support'
</ruby>
-objects do not even respond to +blank?+, let's see how to load its definition.
+objects do not even respond to +blank?+. Let's see how to load its definition.
h5. Cherry-picking a Definition
@@ -40,7 +42,7 @@ h5. Loading Grouped Core Extensions
The next level is to simply load all extensions to +Object+. As a rule of thumb, extensions to +SomeClass+ are available in one shot by loading +active_support/core_ext/some_class+.
-Thus, if that would do, to have +blank?+ available we could just load all extensions to +Object+:
+Thus, to load all extensions to +Object+ (including +blank?+):
<ruby>
require 'active_support/core_ext/object'
@@ -84,32 +86,25 @@ The following values are considered to be blank in a Rails application:
WARNING: Note that numbers are not mentioned, in particular 0 and 0.0 are *not* blank.
-For example, this method from +ActionDispatch::Response+ uses +blank?+ to easily be robust to +nil+ and whitespace strings in one shot:
+For example, this method from +ActionDispatch::Session::AbstractStore+ uses +blank?+ for checking whether a session key is present:
<ruby>
-def charset
- charset = String(headers["Content-Type"] || headers["type"]).split(";")[1]
- charset.blank? ? nil : charset.strip.split("=")[1]
+def ensure_session_key!
+ if @key.blank?
+ raise ArgumentError, 'A key is required...'
+ end
end
</ruby>
-That's a typical use case for +blank?+.
-
-Here, the method Rails runs to instantiate observers upon initialization has nothing to do if there are none:
+The method +present?+ is equivalent to +!blank?+. This example is taken from +ActionDispatch::Http::Cache::Response+:
<ruby>
-def instantiate_observers
- return if @observers.blank?
- # ...
+def set_conditional_cache_control!
+ return if self["Cache-Control"].present?
+ ...
end
</ruby>
-The method +present?+ is equivalent to +!blank?+:
-
-<ruby>
-assert @response.body.present? # same as !@response.body.blank?
-</ruby>
-
NOTE: Defined in +active_support/core_ext/object/blank.rb+.
h4. +presence+
@@ -151,36 +146,31 @@ Active Support provides +duplicable?+ to programmatically query an object about
false.duplicable? # => false
</ruby>
-By definition all objects are +duplicable?+ except +nil+, +false+, +true+, symbols, numbers, and class objects.
+By definition all objects are +duplicable?+ except +nil+, +false+, +true+, symbols, numbers, and class and module objects.
-WARNING. Using +duplicable?+ is discouraged because it depends on a hard-coded list. Classes have means to disallow duplication like removing +dup+ and +clone+ or raising exceptions from them, only +rescue+ can tell.
+WARNING. Any class can disallow duplication removing +dup+ and +clone+ or raising exceptions from them, only +rescue+ can tell whether a given arbitrary object is duplicable. +duplicable?+ depends on the hard-coded list above, but it is much faster than +rescue+. Use it only if you know the hard-coded list is enough in your use case.
NOTE: Defined in +active_support/core_ext/object/duplicable.rb+.
h4. +try+
-Sometimes you want to call a method provided the receiver object is not +nil+, which is something you usually check first.
+Sometimes you want to call a method provided the receiver object is not +nil+, which is something you usually check first. +try+ is like +Object#send+ except that it returns +nil+ if sent to +nil+.
-For instance, note how this method of +ActiveRecord::ConnectionAdapters::AbstractAdapter+ checks if there's a +@logger+:
+For instance, in this code from +ActiveRecord::ConnectionAdapters::AbstractAdapter+ +@logger+ could be +nil+, but you save the check and write in an optimistic style:
<ruby>
def log_info(sql, name, ms)
- if @logger && @logger.debug?
+ if @logger.try(:debug?)
name = '%s (%.1fms)' % [name || 'SQL', ms]
@logger.debug(format_log_entry(name, sql.squeeze(' ')))
end
end
</ruby>
-You can shorten that using +Object#try+. This method is a synonym for +Object#send+ except that it returns +nil+ if sent to +nil+. The previous example could then be rewritten as:
++try+ can also be called without arguments but a block, which will only be executed if the object is not nil:
<ruby>
-def log_info(sql, name, ms)
- if @logger.try(:debug?)
- name = '%s (%.1fms)' % [name || 'SQL', ms]
- @logger.debug(format_log_entry(name, sql.squeeze(' ')))
- end
-end
+@person.try { |p| "#{p.first_name} #{p.last_name}" }
</ruby>
NOTE: Defined in +active_support/core_ext/object/try.rb+.
@@ -364,7 +354,7 @@ That idiom may convey _grouping_ to the reader as well. For example, say you wan
<ruby>
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
</ruby>
@@ -411,39 +401,6 @@ C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
NOTE: Defined in +active_support/core_ext/object/instance_variables.rb+.
-h5. +copy_instance_variables_from(object, exclude = [])+
-
-Copies the instance variables of +object+ into +self+.
-
-Instance variable names in the +exclude+ array are ignored. If +object+
-responds to +protected_instance_variables+ the ones returned are
-also ignored. For example, Rails controllers implement that method.
-
-In both arrays strings and symbols are understood, and they have to include
-the at sign.
-
-<ruby>
-class C
- def initialize(x, y, z)
- @x, @y, @z = x, y, z
- end
-
- def protected_instance_variables
- %w(@z)
- end
-end
-
-a = C.new(0, 1, 2)
-b = C.new(3, 4, 5)
-
-a.copy_instance_variables_from(b, [:@y])
-# a is now: @x = 3, @y = 1, @z = 2
-</ruby>
-
-In the example +object+ and +self+ are of the same type, but they don't need to.
-
-NOTE: Defined in +active_support/core_ext/object/instance_variables.rb+.
-
h4. Silencing Warnings, Streams, and Exceptions
The methods +silence_warnings+ and +enable_warnings+ change the value of +$VERBOSE+ accordingly for the duration of their block, and reset it afterwards:
@@ -475,7 +432,7 @@ h4. +require_library_or_gem+
The convenience method +require_library_or_gem+ tries to load its argument with a regular +require+ first. If it fails loads +rubygems+ and tries again.
-If the first attempt is a failure and +rubygems+ can't be loaded the method raises +LoadError+. On the other hand, if +rubygems+ is available but the argument is not loadable as a gem, the method gives up and +LoadError+ is also raised.
+If the first attempt is a failure and +rubygems+ can't be loaded the method raises +LoadError+. A +LoadError+ is also raised if +rubygems+ is available but the argument is not loadable as a gem.
For example, that's the way the MySQL adapter loads the MySQL library:
@@ -541,12 +498,12 @@ h4. Attributes
h5. +alias_attribute+
-Model attributes have a reader, a writer, and a predicate. You can aliase a model attribute having the corresponding three methods defined for you in one shot. As in other aliasing methods, the new name is the first argument, and the old name is the second (my mnemonic is they go in the same order as if you did an assignment):
+Model attributes have a reader, a writer, and a predicate. You can alias a model attribute having the corresponding three methods defined for you in one shot. As in other aliasing methods, the new name is the first argument, and the old name is the second (my mnemonic is they go in the same order as if you did an assignment):
<ruby>
class User < ActiveRecord::Base
# let me refer to the email column as "login",
- # much meaningful for authentication code
+ # possibly meaningful for authentication code
alias_attribute :login, :email
end
</ruby>
@@ -571,7 +528,7 @@ The default value can be also specified with a block, which is called in the con
class User
attr_accessor :name, :surname
attr_accessor_with_default(:full_name) {
- [name, surname].compact.join(" ")
+ [name, surname].compact.join(" ")
}
end
@@ -606,7 +563,7 @@ h5. Internal Attributes
When you are defining an attribute in a class that is meant to be subclassed name collisions are a risk. That's remarkably important for libraries.
-Active Support defines the macros +attr_internal_reader+, +attr_internal_writer+, and +attr_internal_accessor+. They behave like their Ruby builtin +attr_*+ counterparts, except they name the underlying instance variable in a way that makes collisions less likely.
+Active Support defines the macros +attr_internal_reader+, +attr_internal_writer+, and +attr_internal_accessor+. They behave like their Ruby built-in +attr_*+ counterparts, except they name the underlying instance variable in a way that makes collisions less likely.
The macro +attr_internal+ is a synonym for +attr_internal_accessor+:
@@ -778,7 +735,7 @@ class Counter
end
</ruby>
-The method receives the name of an action, and a +:with+ option with code. The code is evaluated in the context of the receiver each time the method is invoked, and it should evaluate to a +Mutex+ instance or any other object that responds to +synchronize+ and accepts a block.
+The method receives the name of an action, and a +:with+ option with code. The code is evaluated in the context of the receiver each time the method is invoked, and it should evaluate to a +Mutex+ instance or any other object that responds to +synchronize+ and accepts a block.
NOTE: Defined in +active_support/core_ext/module/synchronization.rb+.
@@ -1034,7 +991,7 @@ a2.x # => 2, overridden in a2
The generation of the writer instance method can be prevented by setting the option +:instance_writer+ to false, as in
<ruby>
-module AcitveRecord
+module ActiveRecord
class Base
class_attribute :table_name_prefix, :instance_writer => false
self.table_name_prefix = ""
@@ -1044,7 +1001,7 @@ end
A model may find that option useful as a way to prevent mass-assignment from setting the attribute.
-For convenience +class_attribute+ defines also an instance predicate which is the double negation of what the instance reader returns. In the examples above it would be called +x?+.
+For convenience +class_attribute+ also defines an instance predicate which is the double negation of what the instance reader returns. In the examples above it would be called +x?+.
NOTE: Defined in +active_support/core_ext/class/attribute.rb+
@@ -1088,6 +1045,8 @@ NOTE: Defined in +active_support/core_ext/class/attribute_accessors.rb+.
h4. Class Inheritable Attributes
+WARNING: Class Inheritable Attributes are deprecated. It's recommended that you use +Class#class_attribute+ instead.
+
Class variables are shared down the inheritance tree. Class instance variables are not shared, but they are not inherited either. The macros +class_inheritable_reader+, +class_inheritable_writer+, and +class_inheritable_accessor+ provide accessors for class-level data which is inherited but not shared with children:
<ruby>
@@ -1123,7 +1082,7 @@ module ActiveRecord
end
</ruby>
-Since values are copied when a subclass is defined, if the base class changes the attribute after that, the subclass does not see the new value. That's the point.
+Since values are copied when a subclass is defined, if the base class changes the attribute after that, the subclass does not see the new value. That's the point.
NOTE: Defined in +active_support/core_ext/class/inheritable_attributes.rb+.
@@ -1155,7 +1114,7 @@ NOTE: Defined in +active_support/core_ext/class/subclasses.rb+.
h5. +descendants+
-The +descendants+ method returns all classes that are <tt>&lt;</tt> than its receiver:
+The +descendants+ method returns all classes that are <tt>&lt;</tt> than its receiver:
<ruby>
class C; end
@@ -1232,6 +1191,12 @@ To insert something verbatim use the +raw+ helper rather than calling +html_safe
<%= raw @cms.current_template %> <%# inserts @cms.current_template as is %>
</erb>
+or, equivalently, use <tt><%==</tt>:
+
+<erb>
+<%== @cms.current_template %> <%# inserts @cms.current_template as is %>
+</erb>
+
The +raw+ helper calls +html_safe+ for you:
<ruby>
@@ -1276,7 +1241,7 @@ Pass a +:separator+ to truncate the string at a natural break:
<ruby>
"Oh dear! Oh dear! I shall be late!".truncate(18)
-# => "Oh dear! Oh dea..."
+# => "Oh dear! Oh dea..."
"Oh dear! Oh dear! I shall be late!".truncate(18, :separator => ' ')
# => "Oh dear! Oh..."
</ruby>
@@ -1301,7 +1266,7 @@ Active Support adds that functionality to <tt>%</tt> in previous versions of Rub
NOTE: Defined in +active_support/core_ext/string/interpolation.rb+.
-h4. +starts_with?+ and +ends_width?+
+h4. +starts_with?+ and +ends_with?+
Active Support defines 3rd person aliases of +String#start_with?+ and +String#end_with?+:
@@ -1312,6 +1277,31 @@ Active Support defines 3rd person aliases of +String#start_with?+ and +String#en
NOTE: Defined in +active_support/core_ext/string/starts_ends_with.rb+.
+h4. +strip_heredoc+
+
+The method +strip_heredoc+ strips indentation in heredocs.
+
+For example in
+
+<ruby>
+if options[:usage]
+ puts <<-USAGE.strip_heredoc
+ This command does such and such.
+
+ Supported options are:
+ -h This message
+ ...
+ USAGE
+end
+</ruby>
+
+the user would see the usage message aligned against the left margin.
+
+Technically, it looks for the least indented line in the whole string, and removes
+that amount of leading whitespace.
+
+NOTE: Defined in +active_support/core_ext/string/strip.rb+.
+
h4. Access
h5. +at(position)+
@@ -1580,7 +1570,7 @@ The method +tableize+ is +underscore+ followed by +pluralize+.
"InvoiceLine".tableize # => "invoice_lines"
</ruby>
-As a rule of thumb, +tableize+ returns the table name that corresponds to a given model for simple cases. The actual implementation in Active Record is not straight +tableize+ indeed, because it also demodulizes de class name and checks a few options that may affect the returned string.
+As a rule of thumb, +tableize+ returns the table name that corresponds to a given model for simple cases. The actual implementation in Active Record is not straight +tableize+ indeed, because it also demodulizes the class name and checks a few options that may affect the returned string.
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
@@ -1701,27 +1691,7 @@ foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
-h4. Conversions
-
-h5. +constantize+
-
-The method +constantize+ expects the receiver to contain the name of a constant, and tries to get you the object stored in there, assuming it is defined:
-
-<ruby>
-"ActiveRecord::Base".constantize # => ActiveRecord::Base
-</ruby>
-
-The name is assumed to be top-level, no matter whether it starts with "::" or not. No lexical context is taken into account:
-
-<ruby>
-C = 1
-module M
- C = 2
- "C".constantize # => 1, same as "::C".constantize
-end
-</ruby>
-
-NOTE: Defined in +active_support/core_ext/string/conversions.rb+.
+h4(#string-conversions). Conversions
h5. +ord+
@@ -1767,7 +1737,7 @@ The methods +to_date+, +to_time+, and +to_datetime+ are basically convenience wr
<ruby>
"2010-07-27".to_date # => Tue, 27 Jul 2010
"2010-07-27 23:37:00".to_time # => Tue Jul 27 23:37:00 UTC 2010
-"2010-07-27 23:37:00".to_datetime # => Tue, 27 Jul 2010 23:37:00 +0000
+"2010-07-27 23:37:00".to_datetime # => Tue, 27 Jul 2010 23:37:00 +0000
</ruby>
+to_time+ receives an optional argument +:utc+ or +:local+, to indicate which time zone you want the time in:
@@ -1848,7 +1818,7 @@ h3. Extensions to +Float+
h4. +round+
-The built-in method +Float#round+ rounds a float to the nearest integer. Active Support adds an optional parameter to let you specify a precision:
+The built-in method +Float#round+ rounds a float to the nearest integer. In Ruby 1.9 this method takes an optional argument to let you specify a precision. Active Support adds that functionality to +round+ in previous versions of Ruby:
<ruby>
Math::E.round(4) # => 2.7183
@@ -1900,7 +1870,7 @@ The sum of an empty collection is zero by default, but this is customizable:
[].sum(1) # => 1
</ruby>
-If a block is given +sum+ becomes an iterator that yields the elements of the collection and sums the returned values:
+If a block is given, +sum+ becomes an iterator that yields the elements of the collection and sums the returned values:
<ruby>
(1..5).sum {|n| n * 2 } # => 30
@@ -1928,7 +1898,7 @@ h4. +each_with_object+
The +inject+ method offers iteration with an accumulator:
<ruby>
-[2, 3, 4].inject(1) {|acc, i| product*i } # => 24
+[2, 3, 4].inject(1) {|product, i| product*i } # => 24
</ruby>
The block is expected to return the value for the accumulator in the next iteration, and this makes building mutable objects a bit cumbersome:
@@ -1974,7 +1944,7 @@ The method +many?+ is shorthand for +collection.size > 1+:
<% end %>
</erb>
-If an optional block is given +many?+ only takes into account those elements that return true:
+If an optional block is given, +many?+ only takes into account those elements that return true:
<ruby>
@see_more = videos.many? {|video| video.category == params[:category]}
@@ -1984,7 +1954,7 @@ NOTE: Defined in +active_support/core_ext/enumerable.rb+.
h4. +exclude?+
-The predicate +exclude?+ tests whether a given object does *not* belong to the collection. It is the negation of the builtin +include?+:
+The predicate +exclude?+ tests whether a given object does *not* belong to the collection. It is the negation of the built-in +include?+:
<ruby>
to_visit << node if visited.exclude?(node)
@@ -2039,9 +2009,9 @@ User.exists?(:email => params[:email])
That syntactic sugar is used a lot in Rails to avoid positional arguments where there would be too many, offering instead interfaces that emulate named parameters. In particular it is very idiomatic to use a trailing hash for options.
-If a method expects a variable number of arguments and uses <tt>*</tt> in its declaration, however, such an options hash ends up being an item of the array of arguments, where kind of loses its role.
+If a method expects a variable number of arguments and uses <tt>*</tt> in its declaration, however, such an options hash ends up being an item of the array of arguments, where it loses its role.
-In those cases, you may give an options hash a distinguished treatment with +extract_options!+. That method checks the type of the last item of an array. If it is a hash it pops it and returns it, otherwise returns an empty hash.
+In those cases, you may give an options hash a distinguished treatment with +extract_options!+. This method checks the type of the last item of an array. If it is a hash it pops it and returns it, otherwise it returns an empty hash.
Let's see for example the definition of the +caches_action+ controller macro:
@@ -2057,7 +2027,7 @@ This method receives an arbitrary number of action names, and an optional hash o
NOTE: Defined in +active_support/core_ext/array/extract_options.rb+.
-h4. Conversions
+h4(#array-conversions). Conversions
h5. +to_sentence+
@@ -2222,7 +2192,7 @@ 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>Arraw.wrap</tt> returns such a +nil+ right away.
+* 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 +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.
* It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.
@@ -2242,7 +2212,7 @@ There's also a related idiom that uses the splat operator:
[*object]
</ruby>
-which returns +[nil]+ for +nil+, and calls to <tt>Array(object)</tt> otherwise
+which in Ruby 1.8 returns +[nil]+ for +nil+, and calls to <tt>Array(object)</tt> otherwise. (Please if you know the exact behavior in 1.9 contact fxn.)
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.
@@ -2745,6 +2715,14 @@ WARNING: The original +Range#include?+ is still the one aliased to +Range#===+.
NOTE: Defined in +active_support/core_ext/range/include_range.rb+.
+h4. +cover?+
+
+Ruby 1.9 provides +cover?+, and Active Support defines it for previous versions as an alias for +include?+.
+
+The method +include?+ in Ruby 1.9 is different from the one in 1.8 for non-numeric ranges: instead of being based on comparisons between the value and the range's endpoints, it walks the range with +succ+ looking for value. This works better for ranges with holes, but it has different complexity and may not finish in some other cases.
+
+In Ruby 1.9 the old behavior is still available in the new +cover?+, which Active Support backports for forward compatibility. For example, Rails uses +cover?+ for ranges in +validates_inclusion_of+.
+
h4. +overlaps?+
The method +Range#overlaps?+ says whether any two given ranges have non-void intersection:
@@ -2815,6 +2793,8 @@ h5. +Date.current+
Active Support defines +Date.current+ to be today in the current time zone. That's like +Date.today+, except that it honors the user time zone, if defined. It also defines +Date.yesterday+ and +Date.tomorrow+, and the instance predicates +past?+, +today?+, and +future?+, all of them relative to +Date.current+.
+When making Date comparisons using methods which honor the user time zone, make sure to use +Date.current+ and not +Date.today+. There are cases where the user time zone might be in the future compared to the system time zone, which +Date.today+ uses by default. This means +Date.today+ may equal +Date.yesterday+.
+
h5. Named dates
h6. +prev_year+, +next_year+
@@ -2870,9 +2850,9 @@ d.end_of_week # => Sun, 09 May 2010
+beginning_of_week+ is aliased to +monday+ and +at_beginning_of_week+. +end_of_week+ is aliased to +sunday+ and +at_end_of_week+.
-h6. +next_week+
+h6. +prev_week+, +next_week+
-+next_week+ receives a symbol with a day name in English (in lowercase, default is +:monday+) and it returns the date corresponding to that day in the next week:
+The method +next_week+ receives a symbol with a day name in English (in lowercase, default is +:monday+) and it returns the date corresponding to that day:
<ruby>
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
@@ -2880,6 +2860,14 @@ d.next_week # => Mon, 10 May 2010
d.next_week(:saturday) # => Sat, 15 May 2010
</ruby>
+The method +prev_week+ is analogous:
+
+<ruby>
+d.prev_week # => Mon, 26 Apr 2010
+d.prev_week(:saturday) # => Sat, 01 May 2010
+d.prev_week(:friday) # => Fri, 30 Apr 2010
+</ruby>
+
h6. +beginning_of_month+, +end_of_month+
The methods +beginning_of_month+ and +end_of_month+ return the dates for the beginning and end of the month:
@@ -2957,6 +2945,15 @@ Date.new(2010, 4, 30).months_ago(2) # => Sun, 28 Feb 2010
Date.new(2009, 12, 31).months_since(2) # => Sun, 28 Feb 2010
</ruby>
+h6. +weeks_ago+
+
+The method +weeks_ago+ works analogously for weeks:
+
+<ruby>
+Date.new(2010, 5, 24).weeks_ago(1) # => Mon, 17 May 2010
+Date.new(2010, 5, 24).weeks_ago(2) # => Mon, 10 May 2010
+</ruby>
+
h6. +advance+
The most generic way to jump to other days is +advance+. This method receives a hash with keys +:years+, +:months+, +:weeks+, +:days+, and returns a date advanced as much as the present keys indicate:
@@ -3001,7 +2998,7 @@ Date.new(2010, 1, 31).change(:month => 2)
# => ArgumentError: invalid date
</ruby>
-h5. Durations
+h5(#date-durations). Durations
Durations can be added and substracted to dates:
@@ -3048,14 +3045,14 @@ h6. +ago+, +since+
The method +ago+ receives a number of seconds as argument and returns a timestamp those many seconds ago from midnight:
<ruby>
-date = Date.current # => Fri, 11 Jun 2010
+date = Date.current # => Fri, 11 Jun 2010
date.ago(1) # => Thu, 10 Jun 2010 23:59:59 EDT -04:00
</ruby>
Similarly, +since+ moves forward:
<ruby>
-date = Date.current # => Fri, 11 Jun 2010
+date = Date.current # => Fri, 11 Jun 2010
date.since(1) # => Fri, 11 Jun 2010 00:00:01 EDT -04:00
</ruby>
@@ -3078,6 +3075,8 @@ yesterday
tomorrow
beginning_of_week (monday, at_beginning_of_week)
end_on_week (at_end_of_week)
+weeks_ago
+prev_week
next_week
months_ago
months_since
@@ -3110,7 +3109,7 @@ h5. Named Datetimes
h6. +DateTime.current+
-Active Support defines +DateTime.current+ to be like +Time.now.to_datetime+, except that it honors the user time zone, if defined. It also defines instance predicates +past?+, and +future?+ relative to +DateTime.current+.
+Active Support defines +DateTime.current+ to be like +Time.now.to_datetime+, except that it honors the user time zone, if defined. It also defines +DateTime.yesterday+ and +DateTime.tomorrow+, and the instance predicates +past?+, and +future?+ relative to +DateTime.current+.
h5. Other Extensions
@@ -3207,7 +3206,7 @@ DateTime.current.change(:month => 2, :day => 30)
# => ArgumentError: invalid date
</ruby>
-h5. Durations
+h5(#datetime-durations). Durations
Durations can be added and substracted to datetimes:
@@ -3250,6 +3249,8 @@ beginning_of_day (midnight, at_midnight, at_beginning_of_day)
end_of_day
beginning_of_week (monday, at_beginning_of_week)
end_on_week (at_end_of_week)
+weeks_ago
+prev_week
next_week
months_ago
months_since
@@ -3285,6 +3286,12 @@ t.advance(:seconds => 1)
* If +since+ or +ago+ jump to a time that can't be expressed with +Time+ a +DateTime+ object is returned instead.
+h5. +Time.current+
+
+Active Support defines +Time.current+ to be today in the current time zone. That's like +Time.now+, except that it honors the user time zone, if defined. It also defines +Time.yesterday+ and +Time.tomorrow+, and the instance predicates +past?+, +today?+, and +future?+, all of them relative to +Time.current+.
+
+When making Time comparisons using methods which honor the user time zone, make sure to use +Time.current+ and not +Time.now+. There are cases where the user time zone might be in the future compared to the system time zone, which +Time.today+ uses by default. This means +Time.now+ may equal +Time.yesterday+.
+
h4. Time Constructors
Active Support defines +Time.current+ to be +Time.zone.now+ if there's a user time zone defined, with fallback to +Time.now+:
@@ -3320,7 +3327,7 @@ Both +local_time+ and +utc_time+ accept up to seven positional arguments: year,
If the time to be constructed lies beyond the range supported by +Time+ in the runtime platform, usecs are discarded and a +DateTime+ object is returned instead.
-h5. Durations
+h5(#time-durations). Durations
Durations can be added and substracted to time objects:
@@ -3370,6 +3377,49 @@ The auxiliary file is written in a standard directory for temporary files, but y
NOTE: Defined in +active_support/core_ext/file/atomic.rb+.
+h3. Extensions to +Logger+
+
+h4. +around_[level]+
+
+Takes two arguments, a +before_message+ and +after_message+ and calls the current level method on the +Logger+ instance, passing in the +before_message+, then the specified message, then the +after_message+:
+
+<ruby>
+ logger = Logger.new("log/development.log")
+ logger.around_info("before", "after") { |logger| logger.info("during") }
+</ruby>
+
+h4. +silence+
+
+Silences every log level lesser to the specified one for the duration of the given block. Log level orders are: debug, info, error and fatal.
+
+<ruby>
+ logger = Logger.new("log/development.log")
+ logger.silence(Logger::INFO) do
+ logger.debug("In space, no one can hear you scream.")
+ logger.info("Scream all you want, small mailman!")
+ end
+</ruby>
+
+h4. +datetime_format=+
+
+Modifies the datetime format output by the formatter class associated with this logger. If the formatter class does not have a +datetime_format+ method then this is ignored.
+
+<ruby>
+ class Logger::FormatWithTime < Logger::Formatter
+ cattr_accessor(:datetime_format) { "%Y%m%d%H%m%S" }
+
+ def self.call(severity, timestamp, progname, msg)
+ "#{timestamp.strftime(datetime_format)} -- #{String === msg ? msg : msg.inspect}\n"
+ end
+ end
+
+ logger = Logger.new("log/development.log")
+ logger.formatter = Logger::FormatWithTime
+ logger.info("<- is the current time")
+</ruby>
+
+NOTE: Defined in +active_support/core_ext/logger.rb+.
+
h3. Extensions to +NameError+
Active Support adds +missing_name?+ to +NameError+, which tests whether the exception was raised because of the name passed as argument.
@@ -3418,7 +3468,5 @@ NOTE: Defined in +active_support/core_ext/load_error.rb+.
h3. Changelog
-"Lighthouse ticket":https://rails.lighthouseapp.com/projects/16213/tickets/67
-
* August 10, 2010: Starts to take shape, added to the index.
* April 18, 2009: Initial version by "Xavier Noria":credits.html#fxn