diff options
Diffstat (limited to 'activesupport/lib/active_support/core_ext')
40 files changed, 563 insertions, 626 deletions
diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb index d6ae031c0d..7f37c459c1 100644 --- a/activesupport/lib/active_support/core_ext/array/conversions.rb +++ b/activesupport/lib/active_support/core_ext/array/conversions.rb @@ -142,7 +142,7 @@ class Array # # Otherwise the root element is "objects": # - # [{:foo => 1, :bar => 2}, {:baz => 3}].to_xml + # [{ foo: 1, bar: 2}, { baz: 3}].to_xml # # <?xml version="1.0" encoding="UTF-8"?> # <objects type="array"> @@ -164,7 +164,7 @@ class Array # # To ensure a meaningful root element use the <tt>:root</tt> option: # - # customer_with_no_projects.projects.to_xml(:root => "projects") + # customer_with_no_projects.projects.to_xml(root: 'projects') # # <?xml version="1.0" encoding="UTF-8"?> # <projects type="array"/> @@ -174,7 +174,7 @@ class Array # # The +options+ hash is passed downwards: # - # Message.all.to_xml(:skip_types => true) + # Message.all.to_xml(skip_types: true) # # <?xml version="1.0" encoding="UTF-8"?> # <messages> diff --git a/activesupport/lib/active_support/core_ext/array/extract_options.rb b/activesupport/lib/active_support/core_ext/array/extract_options.rb index 40ceb3eb9e..9008a0df2a 100644 --- a/activesupport/lib/active_support/core_ext/array/extract_options.rb +++ b/activesupport/lib/active_support/core_ext/array/extract_options.rb @@ -17,8 +17,8 @@ class Array # args.extract_options! # end # - # options(1, 2) # => {} - # options(1, 2, :a => :b) # => {:a=>:b} + # options(1, 2) # => {} + # options(1, 2, a: :b) # => {:a=>:b} def extract_options! if last.is_a?(Hash) && last.extractable_options? pop diff --git a/activesupport/lib/active_support/core_ext/array/grouping.rb b/activesupport/lib/active_support/core_ext/array/grouping.rb index a184eb492a..f79b100b3b 100644 --- a/activesupport/lib/active_support/core_ext/array/grouping.rb +++ b/activesupport/lib/active_support/core_ext/array/grouping.rb @@ -83,8 +83,8 @@ class Array # Divides the array into one or more subarrays based on a delimiting +value+ # or the result of an optional block. # - # [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]] - # (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]] + # [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]] + # (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]] def split(value = nil, &block) inject([[]]) do |results, element| if block && block.call(element) || value == element diff --git a/activesupport/lib/active_support/core_ext/array/uniq_by.rb b/activesupport/lib/active_support/core_ext/array/uniq_by.rb index 3bedfa9a61..c1d5a355a4 100644 --- a/activesupport/lib/active_support/core_ext/array/uniq_by.rb +++ b/activesupport/lib/active_support/core_ext/array/uniq_by.rb @@ -4,7 +4,6 @@ class Array # Returns a unique array based on the criteria in the block. # # [1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2] - # def uniq_by(&block) ActiveSupport::Deprecation.warn 'uniq_by is deprecated. Use Array#uniq instead', caller uniq(&block) diff --git a/activesupport/lib/active_support/core_ext/array/wrap.rb b/activesupport/lib/active_support/core_ext/array/wrap.rb index 9ea93d7226..7bf28b2f27 100644 --- a/activesupport/lib/active_support/core_ext/array/wrap.rb +++ b/activesupport/lib/active_support/core_ext/array/wrap.rb @@ -7,32 +7,33 @@ class Array # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned. # * Otherwise, returns an array with the argument as its single element. # - # Array.wrap(nil) # => [] - # Array.wrap([1, 2, 3]) # => [1, 2, 3] - # Array.wrap(0) # => [0] + # Array.wrap(nil) # => [] + # Array.wrap([1, 2, 3]) # => [1, 2, 3] + # Array.wrap(0) # => [0] # # This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences: # # * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt> - # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns - # such a +nil+ right away. + # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns + # such a +nil+ right away. # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt> - # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value. + # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value. # * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array. # # The last point is particularly worth comparing for some enumerables: # - # Array(:foo => :bar) # => [[:foo, :bar]] - # Array.wrap(:foo => :bar) # => [{:foo => :bar}] + # Array(foo: :bar) # => [[:foo, :bar]] + # Array.wrap(foo: :bar) # => [{:foo => :bar}] # # There's also a related idiom that uses the splat operator: # # [*object] # - # which returns <tt>[nil]</tt> for +nil+, and calls to <tt>Array(object)</tt> otherwise. + # which for +nil+ returns <tt>[nil]</tt> (Ruby 1.8.7) or <tt>[]</tt> (Ruby + # 1.9), and calls to <tt>Array(object)</tt> otherwise. # - # Thus, in this case the behavior is different for +nil+, and the differences with - # <tt>Kernel#Array</tt> explained above apply to the rest of +object+s. + # Thus, in this case the behavior may be different for +nil+, and the differences with + # <tt>Kernel#Array</tt> explained above apply to the rest of <tt>object</tt>s. def self.wrap(object) if object.nil? [] diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb index 7b6f8ab0a1..1c3d26ead4 100644 --- a/activesupport/lib/active_support/core_ext/class/attribute.rb +++ b/activesupport/lib/active_support/core_ext/class/attribute.rb @@ -57,16 +57,16 @@ class Class # object.setting # => false # Base.setting # => true # - # To opt out of the instance reader method, pass :instance_reader => false. + # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>. # # object.setting # => NoMethodError # object.setting? # => NoMethodError # - # To opt out of the instance writer method, pass :instance_writer => false. + # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>. # # object.setting = false # => NoMethodError # - # To opt out of both instance methods, pass :instance_accessor => false. + # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>. def class_attribute(*attrs) options = attrs.extract_options! instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true) diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb index 7fe4161fb4..a7551d9c64 100644 --- a/activesupport/lib/active_support/core_ext/date/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date/calculations.rb @@ -3,19 +3,35 @@ require 'active_support/duration' require 'active_support/core_ext/object/acts_like' require 'active_support/core_ext/date/zones' require 'active_support/core_ext/time/zones' +require 'active_support/core_ext/date_and_time/calculations' class Date - DAYS_INTO_WEEK = { - :monday => 0, - :tuesday => 1, - :wednesday => 2, - :thursday => 3, - :friday => 4, - :saturday => 5, - :sunday => 6 - } + include DateAndTime::Calculations class << self + attr_accessor :beginning_of_week_default + + # Returns the week start (e.g. :monday) for the current request, if this has been set (via Date.beginning_of_week=). + # If <tt>Date.beginning_of_week</tt> has not been set for the current request, returns the week start specified in <tt>config.beginning_of_week</tt>. + # If no config.beginning_of_week was specified, returns :monday. + def beginning_of_week + Thread.current[:beginning_of_week] || beginning_of_week_default || :monday + end + + # Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. :monday) for current request/thread. + # + # This method accepts any of the following day symbols: + # :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday + def beginning_of_week=(week_start) + Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start) + end + + # Returns week start day symbol (e.g. :monday), or raises an ArgumentError for invalid day symbol. + def find_beginning_of_week!(week_start) + raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.keys.include?(week_start) + week_start + end + # Returns a new Date representing the date 1 day ago (i.e. yesterday's date). def yesterday ::Date.current.yesterday @@ -32,21 +48,6 @@ class Date end end - # Returns true if the Date object's date lies in the past. Otherwise returns false. - def past? - self < ::Date.current - end - - # Returns true if the Date object's date is today. - def today? - to_date == ::Date.current # we need the to_date because of DateTime - end - - # Returns true if the Date object's date lies in the future. - def future? - self > ::Date.current - end - # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00) # and then subtracts the specified number of seconds. def ago(seconds) @@ -106,9 +107,10 @@ class Date end # Returns a new Date where one or more of the elements have been changed according to the +options+ parameter. + # The +options+ parameter is a hash with a combination of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>. # - # Date.new(2007, 5, 12).change(:day => 1) # => Date.new(2007, 5, 1) - # Date.new(2007, 5, 12).change(:year => 2005, :month => 1) # => Date.new(2005, 1, 12) + # Date.new(2007, 5, 12).change(day: 1) # => Date.new(2007, 5, 1) + # Date.new(2007, 5, 12).change(year: 2005, month: 1) # => Date.new(2005, 1, 12) def change(options) ::Date.new( options.fetch(:year, year), @@ -116,161 +118,4 @@ class Date options.fetch(:day, day) ) end - - # Returns a new Date/DateTime representing the time a number of specified weeks ago. - def weeks_ago(weeks) - advance(:weeks => -weeks) - end - - # Returns a new Date/DateTime representing the time a number of specified months ago. - def months_ago(months) - advance(:months => -months) - end - - # Returns a new Date/DateTime representing the time a number of specified months in the future. - def months_since(months) - advance(:months => months) - end - - # Returns a new Date/DateTime representing the time a number of specified years ago. - def years_ago(years) - advance(:years => -years) - end - - # Returns a new Date/DateTime representing the time a number of specified years in the future. - def years_since(years) - advance(:years => years) - end - - # Returns number of days to start of this week. Week is assumed to start on - # +start_day+, default is +:monday+. - def days_to_week_start(start_day = :monday) - start_day_number = DAYS_INTO_WEEK[start_day] - current_day_number = wday != 0 ? wday - 1 : 6 - (current_day_number - start_day_number) % 7 - end - - # Returns a new +Date+/+DateTime+ representing the start of this week. Week is - # assumed to start on +start_day+, default is +:monday+. +DateTime+ objects - # have their time set to 0:00. - def beginning_of_week(start_day = :monday) - days_to_start = days_to_week_start(start_day) - result = self - days_to_start - acts_like?(:time) ? result.midnight : result - end - alias :at_beginning_of_week :beginning_of_week - - # Returns a new +Date+/+DateTime+ representing the start of this week. Week is - # assumed to start on a Monday. +DateTime+ objects have their time set to 0:00. - def monday - beginning_of_week - end - - # Returns a new +Date+/+DateTime+ representing the end of this week. Week is - # assumed to start on +start_day+, default is +:monday+. +DateTime+ objects - # have their time set to 23:59:59. - def end_of_week(start_day = :monday) - days_to_end = 6 - days_to_week_start(start_day) - result = self + days_to_end.days - acts_like?(:time) ? result.end_of_day : result - end - alias :at_end_of_week :end_of_week - - # Returns a new +Date+/+DateTime+ representing the end of this week. Week is - # assumed to start on a Monday. +DateTime+ objects have their time set to 23:59:59. - def sunday - end_of_week - end - - # Returns a new +Date+/+DateTime+ representing the given +day+ in the previous - # week. Default is +:monday+. +DateTime+ objects have their time set to 0:00. - def prev_week(day = :monday) - result = (self - 7).beginning_of_week + DAYS_INTO_WEEK[day] - acts_like?(:time) ? result.change(:hour => 0) : result - end - alias :last_week :prev_week - - # Alias of prev_month - alias :last_month :prev_month - - # Alias of prev_year - alias :last_year :prev_year - - # Returns a new Date/DateTime representing the start of the given day in next week (default is :monday). - def next_week(day = :monday) - result = (self + 7).beginning_of_week + DAYS_INTO_WEEK[day] - acts_like?(:time) ? result.change(:hour => 0) : result - end - - # Short-hand for months_ago(3) - def prev_quarter - months_ago(3) - end - alias_method :last_quarter, :prev_quarter - - # Short-hand for months_since(3) - def next_quarter - months_since(3) - end - - # Returns a new Date/DateTime representing the start of the month (1st of the month; DateTime objects will have time set to 0:00) - def beginning_of_month - acts_like?(:time) ? change(:day => 1, :hour => 0) : change(:day => 1) - end - alias :at_beginning_of_month :beginning_of_month - - # Returns a new Date/DateTime representing the end of the month (last day of the month; DateTime objects will have time set to 0:00) - def end_of_month - last_day = ::Time.days_in_month(month, year) - if acts_like?(:time) - change(:day => last_day, :hour => 23, :min => 59, :sec => 59) - else - change(:day => last_day) - end - end - alias :at_end_of_month :end_of_month - - # Returns a new Date/DateTime representing the start of the quarter (1st of january, april, july, october; DateTime objects will have time set to 0:00) - def beginning_of_quarter - first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month } - beginning_of_month.change(:month => first_quarter_month) - end - alias :at_beginning_of_quarter :beginning_of_quarter - - # Returns a new Date/DateTime representing the end of the quarter (last day of march, june, september, december; DateTime objects will have time set to 23:59:59) - def end_of_quarter - last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month } - beginning_of_month.change(:month => last_quarter_month).end_of_month - end - alias :at_end_of_quarter :end_of_quarter - - # Returns a new Date/DateTime representing the start of the year (1st of january; DateTime objects will have time set to 0:00) - def beginning_of_year - if acts_like?(:time) - change(:month => 1, :day => 1, :hour => 0) - else - change(:month => 1, :day => 1) - end - end - alias :at_beginning_of_year :beginning_of_year - - # Returns a new Time representing the end of the year (31st of december; DateTime objects will have time set to 23:59:59) - def end_of_year - if acts_like?(:time) - change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59) - else - change(:month => 12, :day => 31) - end - end - alias :at_end_of_year :end_of_year - - # Convenience method which returns a new Date/DateTime representing the time 1 day ago - def yesterday - self - 1 - end - - # Convenience method which returns a new Date/DateTime representing the time 1 day since the instance time - def tomorrow - self + 1 - end end diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb index 81f969e786..9120b0ba49 100644 --- a/activesupport/lib/active_support/core_ext/date/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date/conversions.rb @@ -43,7 +43,7 @@ class Date # # # config/initializers/time_formats.rb # Date::DATE_FORMATS[:month_and_year] = '%B %Y' - # Date::DATE_FORMATS[:short_ordinal] = lambda { |date| date.strftime("%B #{date.day.ordinalize}") } + # Date::DATE_FORMATS[:short_ordinal] = ->(date) { date.strftime("%B #{date.day.ordinalize}") } def to_formatted_s(format = :default) if formatter = DATE_FORMATS[format] if formatter.respond_to?(:call) diff --git a/activesupport/lib/active_support/core_ext/date/zones.rb b/activesupport/lib/active_support/core_ext/date/zones.rb index a70b47b7bc..c1b3934722 100644 --- a/activesupport/lib/active_support/core_ext/date/zones.rb +++ b/activesupport/lib/active_support/core_ext/date/zones.rb @@ -2,8 +2,9 @@ require 'date' require 'active_support/core_ext/time/zones' class Date - # Converts Date to a TimeWithZone in the current zone if Time.zone or Time.zone_default - # is set, otherwise converts Date to a Time via Date#to_time + # Converts Date to a TimeWithZone in the current zone if <tt>Time.zone</tt> or + # <tt>Time.zone_default</tt> is set, otherwise converts Date to a Time via + # Date#to_time. def to_time_in_current_zone if ::Time.zone ::Time.zone.local(year, month, day) diff --git a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb new file mode 100644 index 0000000000..1f78b9eb5a --- /dev/null +++ b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb @@ -0,0 +1,232 @@ +module DateAndTime + module Calculations + DAYS_INTO_WEEK = { + :monday => 0, + :tuesday => 1, + :wednesday => 2, + :thursday => 3, + :friday => 4, + :saturday => 5, + :sunday => 6 + } + + # Returns a new date/time representing yesterday. + def yesterday + advance(:days => -1) + end + + # Returns a new date/time representing tomorrow. + def tomorrow + advance(:days => 1) + end + + # Returns true if the date/time is today. + def today? + to_date == ::Date.current + end + + # Returns true if the date/time is in the past. + def past? + self < self.class.current + end + + # Returns true if the date/time is in the future. + def future? + self > self.class.current + end + + # Returns a new date/time the specified number of days ago. + def days_ago(days) + advance(:days => -days) + end + + # Returns a new date/time the specified number of days in the future. + def days_since(days) + advance(:days => days) + end + + # Returns a new date/time the specified number of weeks ago. + def weeks_ago(weeks) + advance(:weeks => -weeks) + end + + # Returns a new date/time the specified number of weeks in the future. + def weeks_since(weeks) + advance(:weeks => weeks) + end + + # Returns a new date/time the specified number of months ago. + def months_ago(months) + advance(:months => -months) + end + + # Returns a new date/time the specified number of months in the future. + def months_since(months) + advance(:months => months) + end + + # Returns a new date/time the specified number of years ago. + def years_ago(years) + advance(:years => -years) + end + + # Returns a new date/time the specified number of years in the future. + def years_since(years) + advance(:years => years) + end + + # Returns a new date/time at the start of the month. + # DateTime objects will have a time set to 0:00. + def beginning_of_month + first_hour{ change(:day => 1) } + end + alias :at_beginning_of_month :beginning_of_month + + # Returns a new date/time at the start of the quarter. + # Example: 1st January, 1st July, 1st October. + # DateTime objects will have a time set to 0:00. + def beginning_of_quarter + first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month } + beginning_of_month.change(:month => first_quarter_month) + end + alias :at_beginning_of_quarter :beginning_of_quarter + + # Returns a new date/time at the end of the quarter. + # Example: 31st March, 30th June, 30th September. + # DateTIme objects will have a time set to 23:59:59. + def end_of_quarter + last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month } + beginning_of_month.change(:month => last_quarter_month).end_of_month + end + alias :at_end_of_quarter :end_of_quarter + + # Return a new date/time at the beginning of the year. + # Example: 1st January. + # DateTime objects will have a time set to 0:00. + def beginning_of_year + change(:month => 1).beginning_of_month + end + alias :at_beginning_of_year :beginning_of_year + + # Returns a new date/time representing the given day in the next week. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + # DateTime objects have their time set to 0:00. + def next_week(start_day = Date.beginning_of_week) + first_hour{ weeks_since(1).beginning_of_week.days_since(days_span(start_day)) } + end + + # Short-hand for months_since(1). + def next_month + months_since(1) + end + + # Short-hand for months_since(3) + def next_quarter + months_since(3) + end + + # Short-hand for years_since(1). + def next_year + years_since(1) + end + + # Returns a new date/time representing the given day in the previous week. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + # DateTime objects have their time set to 0:00. + def prev_week(start_day = Date.beginning_of_week) + first_hour{ weeks_ago(1).beginning_of_week.days_since(days_span(start_day)) } + end + alias_method :last_week, :prev_week + + # Short-hand for months_ago(1). + def prev_month + months_ago(1) + end + alias_method :last_month, :prev_month + + # Short-hand for months_ago(3). + def prev_quarter + months_ago(3) + end + alias_method :last_quarter, :prev_quarter + + # Short-hand for years_ago(1). + def prev_year + years_ago(1) + end + alias_method :last_year, :prev_year + + # Returns the number of days to the start of the week on the given day. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + def days_to_week_start(start_day = Date.beginning_of_week) + start_day_number = DAYS_INTO_WEEK[start_day] + current_day_number = wday != 0 ? wday - 1 : 6 + (current_day_number - start_day_number) % 7 + end + + # Returns a new date/time representing the start of this week on the given day. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + # +DateTime+ objects have their time set to 0:00. + def beginning_of_week(start_day = Date.beginning_of_week) + result = days_ago(days_to_week_start(start_day)) + acts_like?(:time) ? result.midnight : result + end + alias :at_beginning_of_week :beginning_of_week + + # Returns Monday of this week assuming that week starts on Monday. + # +DateTime+ objects have their time set to 0:00. + def monday + beginning_of_week(:monday) + end + + # Returns a new date/time representing the end of this week on the given day. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + # DateTime objects have their time set to 23:59:59. + def end_of_week(start_day = Date.beginning_of_week) + last_hour{ days_since(6 - days_to_week_start(start_day)) } + end + alias :at_end_of_week :end_of_week + + # Returns Sunday of this week assuming that week starts on Monday. + # +DateTime+ objects have their time set to 23:59:59. + def sunday + end_of_week(:monday) + end + + # Returns a new date/time representing the end of the month. + # DateTime objects will have a time set to 23:59:59. + def end_of_month + last_day = ::Time.days_in_month(month, year) + last_hour{ days_since(last_day - day) } + end + alias :at_end_of_month :end_of_month + + # Returns a new date/time representing the end of the year. + # DateTime objects will have a time set to 23:59:59. + def end_of_year + change(:month => 12).end_of_month + end + alias :at_end_of_year :end_of_year + + private + + def first_hour + result = yield + acts_like?(:time) ? result.change(:hour => 0) : result + end + + def last_hour + result = yield + acts_like?(:time) ? result.end_of_day : result + end + + def days_span(day) + (DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7 + end + end +end diff --git a/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_time/calculations.rb index fd78044b5d..385aa586bb 100644 --- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb @@ -9,30 +9,40 @@ class DateTime ::Time.local(2012).utc_offset.to_r / 86400 end - # Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise returns <tt>Time.now.to_datetime</tt>. + # Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or + # <tt>config.time_zone</tt> are set, otherwise returns + # <tt>Time.now.to_datetime</tt>. def current ::Time.zone ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime end end - # Tells whether the DateTime object's datetime lies in the past + # Tells whether the DateTime object's datetime lies in the past. def past? self < ::DateTime.current end - # Tells whether the DateTime object's datetime lies in the future + # Tells whether the DateTime object's datetime lies in the future. def future? self > ::DateTime.current end - # Seconds since midnight: DateTime.now.seconds_since_midnight + # Seconds since midnight: DateTime.now.seconds_since_midnight. def seconds_since_midnight sec + (min * 60) + (hour * 3600) end - # Returns a new DateTime where one or more of the elements have been changed according to the +options+ parameter. The time options - # (hour, minute, sec) reset cascadingly, so if only the hour is passed, then minute and sec is set to 0. If the hour and - # minute is passed, then sec is set to 0. + # Returns a new DateTime where one or more of the elements have been changed + # according to the +options+ parameter. The time options (<tt>:hour</tt>, + # <tt>:minute</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is + # passed, then minute and sec is set to 0. If the hour and minute is passed, + # then sec is set to 0. The +options+ parameter takes a hash with any of these + # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, + # <tt>:min</tt>, <tt>:sec</tt>, <tt>:offset</tt>, <tt>:start</tt>. + # + # DateTime.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => DateTime.new(2012, 8, 1, 22, 35, 0) + # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => DateTime.new(1981, 8, 1, 22, 35, 0) + # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0) def change(options) ::DateTime.civil( options.fetch(:year, year), @@ -65,20 +75,21 @@ class DateTime end end - # Returns a new DateTime representing the time a number of seconds ago + # Returns a new DateTime representing the time a number of seconds ago. # Do not use this method in combination with x.months, use months_ago instead! def ago(seconds) since(-seconds) end - # Returns a new DateTime representing the time a number of seconds since the instance time - # Do not use this method in combination with x.months, use months_since instead! + # Returns a new DateTime representing the time a number of seconds since the + # instance time. Do not use this method in combination with x.months, use + # months_since instead! def since(seconds) self + Rational(seconds.round, 86400) end alias :in :since - # Returns a new DateTime representing the start of the day (0:00) + # Returns a new DateTime representing the start of the day (0:00). def beginning_of_day change(:hour => 0) end @@ -86,42 +97,43 @@ class DateTime alias :at_midnight :beginning_of_day alias :at_beginning_of_day :beginning_of_day - # Returns a new DateTime representing the end of the day (23:59:59) + # Returns a new DateTime representing the end of the day (23:59:59). def end_of_day change(:hour => 23, :min => 59, :sec => 59) end - # Returns a new DateTime representing the start of the hour (hh:00:00) + # Returns a new DateTime representing the start of the hour (hh:00:00). def beginning_of_hour change(:min => 0) end alias :at_beginning_of_hour :beginning_of_hour - # Returns a new DateTime representing the end of the hour (hh:59:59) + # Returns a new DateTime representing the end of the hour (hh:59:59). def end_of_hour change(:min => 59, :sec => 59) end - # Adjusts DateTime to UTC by adding its offset value; offset is set to 0 + # Adjusts DateTime to UTC by adding its offset value; offset is set to 0. # - # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600 - # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000 + # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600 + # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000 def utc new_offset(0) end alias_method :getutc, :utc - # Returns true if offset == 0 + # Returns +true+ if <tt>offset == 0</tt>. def utc? offset == 0 end - # Returns the offset value in seconds + # Returns the offset value in seconds. def utc_offset (offset * 86400).to_i end - # Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTime + # Layers additional behavior on DateTime#<=> so that Time and + # ActiveSupport::TimeWithZone instances can be compared with a DateTime. def <=>(other) super other.to_datetime end diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb index 7c3a5eaace..b7d8414a9d 100644 --- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb @@ -53,7 +53,8 @@ class DateTime alias_method :default_inspect, :inspect alias_method :inspect, :readable_inspect - # Returns DateTime with local offset for given year if format is local else offset is zero + # Returns DateTime with local offset for given year if format is local else + # offset is zero. # # DateTime.civil_from_format :local, 2012 # # => Sun, 01 Jan 2012 00:00:00 +0300 @@ -68,12 +69,12 @@ class DateTime civil(year, month, day, hour, min, sec, offset) end - # Converts self to a floating-point number of seconds since the Unix epoch. + # Converts +self+ to a floating-point number of seconds since the Unix epoch. def to_f seconds_since_unix_epoch.to_f end - # Converts self to an integer number of seconds since the Unix epoch. + # Converts +self+ to an integer number of seconds since the Unix epoch. def to_i seconds_since_unix_epoch.to_i end diff --git a/activesupport/lib/active_support/core_ext/date_time/zones.rb b/activesupport/lib/active_support/core_ext/date_time/zones.rb index 823735d3e2..6457ffbaf6 100644 --- a/activesupport/lib/active_support/core_ext/date_time/zones.rb +++ b/activesupport/lib/active_support/core_ext/date_time/zones.rb @@ -6,13 +6,14 @@ class DateTime # Time.zone = 'Hawaii' # => 'Hawaii' # DateTime.new(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00 # - # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone - # instead of the operating system's time zone. + # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> + # as the local zone instead of the operating system's time zone. # - # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument, - # and the conversion will be based on that zone instead of <tt>Time.zone</tt>. + # You can also pass in a TimeZone instance or string that identifies a TimeZone + # as an argument, and the conversion will be based on that zone instead of + # <tt>Time.zone</tt>. # - # DateTime.new(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00 + # DateTime.new(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00 def in_time_zone(zone = ::Time.zone) if zone ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone)) diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index 03efe6a19a..4501b7ff58 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -17,7 +17,6 @@ module Enumerable # The default sum of an empty list is zero. You can override this default: # # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0) - # def sum(identity = 0, &block) if block_given? map(&block).sum(identity) @@ -32,7 +31,6 @@ module Enumerable # => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...} # people.index_by { |person| "#{person.first_name} #{person.last_name}" } # => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...} - # def index_by if block_given? Hash[map { |elem| [yield(elem), elem] }] @@ -41,8 +39,10 @@ module Enumerable end end - # Returns true if the enumerable has more than 1 element. Functionally equivalent to enum.to_a.size > 1. - # Can be called with a block too, much like any?, so <tt>people.many? { |p| p.age > 26 }</tt> returns true if more than one person is over 26. + # Returns +true+ if the enumerable has more than 1 element. Functionally + # equivalent to <tt>enum.to_a.size > 1</tt>. Can be called with a block too, + # much like any?, so <tt>people.many? { |p| p.age > 26 }</tt> returns +true+ + # if more than one person is over 26. def many? cnt = 0 if block_given? @@ -55,7 +55,8 @@ module Enumerable end end - # The negative of the <tt>Enumerable#include?</tt>. Returns true if the collection does not include the object. + # The negative of the <tt>Enumerable#include?</tt>. Returns +true+ if the + # collection does not include the object. def exclude?(object) !include?(object) end diff --git a/activesupport/lib/active_support/core_ext/file/atomic.rb b/activesupport/lib/active_support/core_ext/file/atomic.rb index 9e504851e7..81beb4e85d 100644 --- a/activesupport/lib/active_support/core_ext/file/atomic.rb +++ b/activesupport/lib/active_support/core_ext/file/atomic.rb @@ -1,3 +1,5 @@ +require 'fileutils' + class File # Write to a file atomically. Useful for situations where you don't # want other processes or threads to see half-written files. @@ -25,17 +27,9 @@ class File # Get original file permissions old_stat = stat(file_name) rescue Errno::ENOENT - # No old permissions, write a temp file to determine the defaults - temp_file_name = [ - '.permissions_check', - Thread.current.object_id, - Process.pid, - rand(1000000) - ].join('.') - check_name = join(dirname(file_name), temp_file_name) - open(check_name, 'w') { } - old_stat = stat(check_name) - unlink(check_name) + # If not possible, probe which are the default permissions in the + # destination directory. + old_stat = probe_stat_in(dirname(file_name)) end # Overwrite original file with temp file @@ -45,4 +39,20 @@ class File chown(old_stat.uid, old_stat.gid, file_name) chmod(old_stat.mode, file_name) end + + # Private utility method. + def self.probe_stat_in(dir) #:nodoc: + basename = [ + '.permissions_check', + Thread.current.object_id, + Process.pid, + rand(1000000) + ].join('.') + + file_name = join(dir, basename) + FileUtils.touch(file_name) + stat(file_name) + ensure + FileUtils.rm_f(file_name) if file_name + end end diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb index 7c72ead36c..5ba8197006 100644 --- a/activesupport/lib/active_support/core_ext/hash/conversions.rb +++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb @@ -40,7 +40,7 @@ class Hash # end # end # - # {:foo => Foo.new}.to_xml(:skip_instruct => true) + # { foo: Foo.new }.to_xml(skip_instruct: true) # # => "<hash><bar>fooing!</bar></hash>" # # * Otherwise, a node with +key+ as tag is created with a string representation of diff --git a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb index 023bf68a87..83f0c87b04 100644 --- a/activesupport/lib/active_support/core_ext/hash/deep_merge.rb +++ b/activesupport/lib/active_support/core_ext/hash/deep_merge.rb @@ -1,20 +1,26 @@ class Hash # Returns a new hash with +self+ and +other_hash+ merged recursively. # - # h1 = {x: {y: [4,5,6]}, z: [7,8,9]} - # h2 = {x: {y: [7,8,9]}, z: "xyz"} + # h1 = { x: { y: [4,5,6] }, z: [7,8,9] } + # h2 = { x: { y: [7,8,9] }, z: 'xyz' } # # h1.deep_merge(h2) #=> {:x => {:y => [7, 8, 9]}, :z => "xyz"} # h2.deep_merge(h1) #=> {:x => {:y => [4, 5, 6]}, :z => [7, 8, 9]} - def deep_merge(other_hash) - dup.deep_merge!(other_hash) + # h1.deep_merge(h2) { |key, old, new| Array.wrap(old) + Array.wrap(new) } + # #=> {:x => {:y => [4, 5, 6, 7, 8, 9]}, :z => [7, 8, 9, "xyz"]} + def deep_merge(other_hash, &block) + dup.deep_merge!(other_hash, &block) end # Same as +deep_merge+, but modifies +self+. - def deep_merge!(other_hash) + def deep_merge!(other_hash, &block) other_hash.each_pair do |k,v| tv = self[k] - self[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_merge(v) : v + if tv.is_a?(Hash) && v.is_a?(Hash) + self[k] = tv.deep_merge(v, &block) + else + self[k] = block && tv ? block.call(k, tv, v) : v + end end self end diff --git a/activesupport/lib/active_support/core_ext/hash/except.rb b/activesupport/lib/active_support/core_ext/hash/except.rb index c82da3c6c2..5cb00d0ebd 100644 --- a/activesupport/lib/active_support/core_ext/hash/except.rb +++ b/activesupport/lib/active_support/core_ext/hash/except.rb @@ -3,7 +3,6 @@ class Hash # limiting a set of parameters to everything but a few known toggles: # # @person.update_attributes(params[:person].except(:admin)) - # def except(*keys) dup.except!(*keys) end diff --git a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb index 7d54c9fae6..6c7e876fca 100644 --- a/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb +++ b/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb @@ -4,8 +4,7 @@ class Hash # Returns an <tt>ActiveSupport::HashWithIndifferentAccess</tt> out of its receiver: # - # {:a => 1}.with_indifferent_access["a"] # => 1 - # + # { a: 1 }.with_indifferent_access['a'] # => 1 def with_indifferent_access ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self) end @@ -17,8 +16,7 @@ class Hash # converting to an <tt>ActiveSupport::HashWithIndifferentAccess</tt> would not be # desirable. # - # b = {:b => 1} - # {:a => b}.with_indifferent_access["a"] # calls b.nested_under_indifferent_access - # + # b = { b: 1 } + # { a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access alias nested_under_indifferent_access with_indifferent_access end diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb index e753e36124..13081995b0 100644 --- a/activesupport/lib/active_support/core_ext/hash/keys.rb +++ b/activesupport/lib/active_support/core_ext/hash/keys.rb @@ -14,7 +14,7 @@ class Hash end # Destructively convert all keys using the block operations. - # Same as transform_keys but modifies +self+ + # Same as transform_keys but modifies +self+. def transform_keys! keys.each do |key| self[yield(key)] = delete(key) @@ -57,13 +57,13 @@ class Hash end alias_method :to_options!, :symbolize_keys! - # Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. - # Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols - # as keys, this will fail. + # Validate all keys in a hash match <tt>*valid_keys</tt>, raising ArgumentError + # on a mismatch. Note that keys are NOT treated indifferently, meaning if you + # use strings for keys but assert symbols as keys, this will fail. # - # { :name => 'Rob', :years => '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: years" - # { :name => 'Rob', :age => '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: name" - # { :name => 'Rob', :age => '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing + # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: years" + # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: name" + # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing def assert_valid_keys(*valid_keys) valid_keys.flatten! each_key do |k| diff --git a/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb b/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb index 6074103484..fbb482435d 100644 --- a/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb +++ b/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb @@ -1,11 +1,11 @@ class Hash # Merges the caller into +other_hash+. For example, # - # options = options.reverse_merge(:size => 25, :velocity => 10) + # options = options.reverse_merge(size: 25, velocity: 10) # # is equivalent to # - # options = {:size => 25, :velocity => 10}.merge(options) + # options = { size: 25, velocity: 10 }.merge(options) # # This is particularly useful for initializing an options hash # with default values. diff --git a/activesupport/lib/active_support/core_ext/hash/slice.rb b/activesupport/lib/active_support/core_ext/hash/slice.rb index b862b5ae2a..45fec57009 100644 --- a/activesupport/lib/active_support/core_ext/hash/slice.rb +++ b/activesupport/lib/active_support/core_ext/hash/slice.rb @@ -3,7 +3,7 @@ class Hash # limiting an options hash to valid keys before passing to a method: # # def search(criteria = {}) - # assert_valid_keys(:mass, :velocity, :time) + # criteria.assert_valid_keys(:mass, :velocity, :time) # end # # search(options.slice(:mass, :velocity, :time)) @@ -19,7 +19,9 @@ class Hash # Replaces the hash with only the given keys. # Returns a hash containing the removed key/value pairs. - # {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d => 4} + # + # { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b) + # # => {:c => 3, :d => 4} def slice!(*keys) keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true) omit = slice(*self.keys - keys) @@ -29,7 +31,9 @@ class Hash end # Removes and returns the key/value pairs matching the given keys. - # {:a => 1, :b => 2, :c => 3, :d => 4}.extract!(:a, :b) # => {:a => 1, :b => 2} + # + # { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) + # # => {:a => 1, :b => 2} def extract!(*keys) keys.each_with_object({}) { |key, result| result[key] = delete(key) } end diff --git a/activesupport/lib/active_support/core_ext/integer/inflections.rb b/activesupport/lib/active_support/core_ext/integer/inflections.rb index 1e30687166..56f2ed5985 100644 --- a/activesupport/lib/active_support/core_ext/integer/inflections.rb +++ b/activesupport/lib/active_support/core_ext/integer/inflections.rb @@ -10,7 +10,6 @@ class Integer # 1003.ordinalize # => "1003rd" # -11.ordinalize # => "-11th" # -1001.ordinalize # => "-1001st" - # def ordinalize ActiveSupport::Inflector.ordinalize(self) end @@ -24,7 +23,6 @@ class Integer # 1003.ordinal # => "rd" # -11.ordinal # => "th" # -1001.ordinal # => "st" - # def ordinal ActiveSupport::Inflector.ordinal(self) end diff --git a/activesupport/lib/active_support/core_ext/integer/time.rb b/activesupport/lib/active_support/core_ext/integer/time.rb index 894b5d0696..9fb4f6b73a 100644 --- a/activesupport/lib/active_support/core_ext/integer/time.rb +++ b/activesupport/lib/active_support/core_ext/integer/time.rb @@ -1,21 +1,23 @@ class Integer - # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years. + # Enables the use of time calculations and declarations, like <tt>45.minutes + + # 2.hours + 4.years</tt>. # - # These methods use Time#advance for precise date calculations when using from_now, ago, etc. - # as well as adding or subtracting their results from a Time object. For example: + # These methods use Time#advance for precise date calculations when using + # <tt>from_now</tt>, +ago+, etc. as well as adding or subtracting their + # results from a Time object. # - # # equivalent to Time.now.advance(:months => 1) + # # equivalent to Time.now.advance(months: 1) # 1.month.from_now # - # # equivalent to Time.now.advance(:years => 2) + # # equivalent to Time.now.advance(years: 2) # 2.years.from_now # - # # equivalent to Time.now.advance(:months => 4, :years => 5) + # # equivalent to Time.now.advance(months: 4, years: 5) # (4.months + 5.years).from_now # - # While these methods provide precise calculation when used as in the examples above, care - # should be taken to note that this is not true if the result of `months', `years', etc is - # converted before use: + # While these methods provide precise calculation when used as in the examples + # above, care should be taken to note that this is not true if the result of + # +months+, +years+, etc is converted before use: # # # equivalent to 30.days.to_i.from_now # 1.month.to_i.from_now diff --git a/activesupport/lib/active_support/core_ext/kernel/reporting.rb b/activesupport/lib/active_support/core_ext/kernel/reporting.rb index ad3f9ebec9..bc97da6ef2 100644 --- a/activesupport/lib/active_support/core_ext/kernel/reporting.rb +++ b/activesupport/lib/active_support/core_ext/kernel/reporting.rb @@ -1,7 +1,8 @@ require 'rbconfig' module Kernel - # Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards. + # Sets $VERBOSE to nil for the duration of the block and back to its original + # value afterwards. # # silence_warnings do # value = noisy_call # no warning voiced @@ -12,12 +13,14 @@ module Kernel with_warnings(nil) { yield } end - # Sets $VERBOSE to true for the duration of the block and back to its original value afterwards. + # Sets $VERBOSE to +true+ for the duration of the block and back to its + # original value afterwards. def enable_warnings with_warnings(true) { yield } end - # Sets $VERBOSE for the duration of the block and back to its original value afterwards. + # Sets $VERBOSE for the duration of the block and back to its original + # value afterwards. def with_warnings(flag) old_verbose, $VERBOSE = $VERBOSE, flag yield @@ -65,7 +68,6 @@ module Kernel # # stream = capture(:stdout) { puts 'Cool' } # stream # => "Cool\n" - # def capture(stream) begin stream = stream.to_s @@ -83,7 +85,6 @@ module Kernel # Silences both STDOUT and STDERR, even for subprocesses. # # quietly { system 'bundle install' } - # def quietly silence_stream(STDOUT) do silence_stream(STDERR) do diff --git a/activesupport/lib/active_support/core_ext/module/anonymous.rb b/activesupport/lib/active_support/core_ext/module/anonymous.rb index 0a9e791030..b0c7b021db 100644 --- a/activesupport/lib/active_support/core_ext/module/anonymous.rb +++ b/activesupport/lib/active_support/core_ext/module/anonymous.rb @@ -13,7 +13,6 @@ class Module # m = Module.new # creates an anonymous module # M = m # => m gets a name here as a side-effect # m.name # => "M" - # def anonymous? name.nil? end diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index 39a1240c61..e608eeaf42 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -18,7 +18,7 @@ class Module # # class Foo < ActiveRecord::Base # belongs_to :greeter - # delegate :hello, :to => :greeter + # delegate :hello, to: :greeter # end # # Foo.new.hello # => "hello" @@ -28,7 +28,7 @@ class Module # # class Foo < ActiveRecord::Base # belongs_to :greeter - # delegate :hello, :goodbye, :to => :greeter + # delegate :hello, :goodbye, to: :greeter # end # # Foo.new.goodbye # => "goodbye" @@ -43,15 +43,27 @@ class Module # def initialize # @instance_array = [8,9,10,11] # end - # delegate :sum, :to => :CONSTANT_ARRAY - # delegate :min, :to => :@@class_array - # delegate :max, :to => :@instance_array + # delegate :sum, to: :CONSTANT_ARRAY + # delegate :min, to: :@@class_array + # delegate :max, to: :@instance_array # end # # Foo.new.sum # => 6 # Foo.new.min # => 4 # Foo.new.max # => 11 # + # It's also possible to delegate a method to the class by using +:class+: + # + # class Foo + # def self.hello + # "world" + # end + # + # delegate :hello, to: :class + # end + # + # Foo.new.hello # => "world" + # # Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value # is <tt>true</tt>, the delegate methods are prefixed with the name of the object being # delegated to. @@ -59,7 +71,7 @@ class Module # Person = Struct.new(:name, :address) # # class Invoice < Struct.new(:client) - # delegate :name, :address, :to => :client, :prefix => true + # delegate :name, :address, to: :client, prefix: true # end # # john_doe = Person.new('John Doe', 'Vimmersvej 13') @@ -70,7 +82,7 @@ class Module # It is also possible to supply a custom prefix. # # class Invoice < Struct.new(:client) - # delegate :name, :address, :to => :client, :prefix => :customer + # delegate :name, :address, to: :client, prefix: :customer # end # # invoice = Invoice.new(john_doe) @@ -86,7 +98,7 @@ class Module # def initialize(bar = nil) # @bar = bar # end - # delegate :zoo, :to => :bar + # delegate :zoo, to: :bar # end # # Foo.new.zoo # raises NoMethodError exception (you called nil.zoo) @@ -96,15 +108,14 @@ class Module # def initialize(bar = nil) # @bar = bar # end - # delegate :zoo, :to => :bar, :allow_nil => true + # delegate :zoo, to: :bar, allow_nil: true # end # # Foo.new.zoo # returns nil - # def delegate(*methods) options = methods.pop unless options.is_a?(Hash) && to = options[:to] - raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter).' + raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).' end prefix, allow_nil = options.values_at(:prefix, :allow_nil) @@ -123,6 +134,9 @@ class Module file, line = caller.first.split(':', 2) line = line.to_i + to = to.to_s + to = 'self.class' if to == 'class' + methods.each do |method| # Attribute writer methods only accept one argument. Makes sure []= # methods still accept two arguments. diff --git a/activesupport/lib/active_support/core_ext/module/deprecation.rb b/activesupport/lib/active_support/core_ext/module/deprecation.rb index 9e77ac3c45..34ec6a3d8f 100644 --- a/activesupport/lib/active_support/core_ext/module/deprecation.rb +++ b/activesupport/lib/active_support/core_ext/module/deprecation.rb @@ -1,10 +1,24 @@ require 'active_support/deprecation/method_wrappers' class Module - # Declare that a method has been deprecated. # deprecate :foo # deprecate :bar => 'message' # deprecate :foo, :bar, :baz => 'warning!', :qux => 'gone!' + # + # You can also use custom deprecator instance: + # + # deprecate :foo, :deprecator => MyLib::Deprecator.new + # deprecate :foo, :bar => "warning!", :deprecator => MyLib::Deprecator.new + # + # \Custom deprecators must respond to <tt>deprecation_warning(deprecated_method_name, message, caller_backtrace)</tt> + # method where you can implement your custom warning behavior. + # + # class MyLib::Deprecator + # def deprecation_warning(deprecated_method_name, message, caller_backtrace) + # message = "#{method_name} is deprecated and will be removed from MyLibrary | #{message}" + # Kernel.warn message + # end + # end def deprecate(*method_names) ActiveSupport::Deprecation.deprecate_methods(self, *method_names) end diff --git a/activesupport/lib/active_support/core_ext/module/introspection.rb b/activesupport/lib/active_support/core_ext/module/introspection.rb index 3c8e811fa4..649a969149 100644 --- a/activesupport/lib/active_support/core_ext/module/introspection.rb +++ b/activesupport/lib/active_support/core_ext/module/introspection.rb @@ -27,7 +27,6 @@ class Module # # M.parent # => Object # Module.new.parent # => Object - # def parent parent_name ? ActiveSupport::Inflector.constantize(parent_name) : Object end @@ -44,7 +43,6 @@ class Module # M.parents # => [Object] # M::N.parents # => [M, Object] # X.parents # => [M, Object] - # def parents parents = [] if parent_name diff --git a/activesupport/lib/active_support/core_ext/numeric/conversions.rb b/activesupport/lib/active_support/core_ext/numeric/conversions.rb index 2bbfa78639..6d3635c69a 100644 --- a/activesupport/lib/active_support/core_ext/numeric/conversions.rb +++ b/activesupport/lib/active_support/core_ext/numeric/conversions.rb @@ -14,89 +14,89 @@ class Numeric # ==== Examples # # Phone Numbers: - # 5551234.to_s(:phone) # => 555-1234 - # 1235551234.to_s(:phone) # => 123-555-1234 - # 1235551234.to_s(:phone, :area_code => true) # => (123) 555-1234 - # 1235551234.to_s(:phone, :delimiter => " ") # => 123 555 1234 - # 1235551234.to_s(:phone, :area_code => true, :extension => 555) # => (123) 555-1234 x 555 - # 1235551234.to_s(:phone, :country_code => 1) # => +1-123-555-1234 - # 1235551234.to_s(:phone, :country_code => 1, :extension => 1343, :delimiter => ".") + # 5551234.to_s(:phone) # => 555-1234 + # 1235551234.to_s(:phone) # => 123-555-1234 + # 1235551234.to_s(:phone, area_code: true) # => (123) 555-1234 + # 1235551234.to_s(:phone, delimiter: ' ') # => 123 555 1234 + # 1235551234.to_s(:phone, area_code: true, extension: 555) # => (123) 555-1234 x 555 + # 1235551234.to_s(:phone, country_code: 1) # => +1-123-555-1234 + # 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.') # # => +1.123.555.1234 x 1343 # # Currency: - # 1234567890.50.to_s(:currency) # => $1,234,567,890.50 - # 1234567890.506.to_s(:currency) # => $1,234,567,890.51 - # 1234567890.506.to_s(:currency, :precision => 3) # => $1,234,567,890.506 - # 1234567890.506.to_s(:currency, :locale => :fr) # => 1 234 567 890,51 € - # -1234567890.50.to_s(:currency, :negative_format => "(%u%n)") + # 1234567890.50.to_s(:currency) # => $1,234,567,890.50 + # 1234567890.506.to_s(:currency) # => $1,234,567,890.51 + # 1234567890.506.to_s(:currency, precision: 3) # => $1,234,567,890.506 + # 1234567890.506.to_s(:currency, locale: :fr) # => 1 234 567 890,51 € + # -1234567890.50.to_s(:currency, negative_format: '(%u%n)') # # => ($1,234,567,890.50) - # 1234567890.50.to_s(:currency, :unit => "£", :separator => ",", :delimiter => "") + # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '') # # => £1234567890,50 - # 1234567890.50.to_s(:currency, :unit => "£", :separator => ",", :delimiter => "", :format => "%n %u") + # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u') # # => 1234567890,50 £ # # Percentage: - # 100.to_s(:percentage) # => 100.000% - # 100.to_s(:percentage, :precision => 0) # => 100% - # 1000.to_s(:percentage, :delimiter => '.', :separator => ',') # => 1.000,000% - # 302.24398923423.to_s(:percentage, :precision => 5) # => 302.24399% - # 1000.to_s(:percentage, :locale => :fr) # => 1 000,000% - # 100.to_s(:percentage, :format => "%n %") # => 100 % + # 100.to_s(:percentage) # => 100.000% + # 100.to_s(:percentage, precision: 0) # => 100% + # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => 1.000,000% + # 302.24398923423.to_s(:percentage, precision: 5) # => 302.24399% + # 1000.to_s(:percentage, locale: :fr) # => 1 000,000% + # 100.to_s(:percentage, format: '%n %') # => 100 % # # Delimited: - # 12345678.to_s(:delimited) # => 12,345,678 - # 12345678.05.to_s(:delimited) # => 12,345,678.05 - # 12345678.to_s(:delimited, :delimiter => ".") # => 12.345.678 - # 12345678.to_s(:delimited, :delimiter => ",") # => 12,345,678 - # 12345678.05.to_s(:delimited, :separator => " ") # => 12,345,678 05 - # 12345678.05.to_s(:delimited, :locale => :fr) # => 12 345 678,05 - # 98765432.98.to_s(:delimited, :delimiter => " ", :separator => ",") + # 12345678.to_s(:delimited) # => 12,345,678 + # 12345678.05.to_s(:delimited) # => 12,345,678.05 + # 12345678.to_s(:delimited, delimiter: '.') # => 12.345.678 + # 12345678.to_s(:delimited, delimiter: ',') # => 12,345,678 + # 12345678.05.to_s(:delimited, separator: ' ') # => 12,345,678 05 + # 12345678.05.to_s(:delimited, locale: :fr) # => 12 345 678,05 + # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',') # # => 98 765 432,98 # # Rounded: - # 111.2345.to_s(:rounded) # => 111.235 - # 111.2345.to_s(:rounded, :precision => 2) # => 111.23 - # 13.to_s(:rounded, :precision => 5) # => 13.00000 - # 389.32314.to_s(:rounded, :precision => 0) # => 389 - # 111.2345.to_s(:rounded, :significant => true) # => 111 - # 111.2345.to_s(:rounded, :precision => 1, :significant => true) # => 100 - # 13.to_s(:rounded, :precision => 5, :significant => true) # => 13.000 - # 111.234.to_s(:rounded, :locale => :fr) # => 111,234 - # 13.to_s(:rounded, :precision => 5, :significant => true, :strip_insignificant_zeros => true) + # 111.2345.to_s(:rounded) # => 111.235 + # 111.2345.to_s(:rounded, precision: 2) # => 111.23 + # 13.to_s(:rounded, precision: 5) # => 13.00000 + # 389.32314.to_s(:rounded, precision: 0) # => 389 + # 111.2345.to_s(:rounded, significant: true) # => 111 + # 111.2345.to_s(:rounded, precision: 1, significant: true) # => 100 + # 13.to_s(:rounded, precision: 5, significant: true) # => 13.000 + # 111.234.to_s(:rounded, locale: :fr) # => 111,234 + # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true) # # => 13 - # 389.32314.to_s(:rounded, :precision => 4, :significant => true) # => 389.3 - # 1111.2345.to_s(:rounded, :precision => 2, :separator => ',', :delimiter => '.') + # 389.32314.to_s(:rounded, precision: 4, significant: true) # => 389.3 + # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.') # # => 1.111,23 # # Human-friendly size in Bytes: - # 123.to_s(:human_size) # => 123 Bytes - # 1234.to_s(:human_size) # => 1.21 KB - # 12345.to_s(:human_size) # => 12.1 KB - # 1234567.to_s(:human_size) # => 1.18 MB - # 1234567890.to_s(:human_size) # => 1.15 GB - # 1234567890123.to_s(:human_size) # => 1.12 TB - # 1234567.to_s(:human_size, :precision => 2) # => 1.2 MB - # 483989.to_s(:human_size, :precision => 2) # => 470 KB - # 1234567.to_s(:human_size, :precision => 2, :separator => ',') # => 1,2 MB - # 1234567890123.to_s(:human_size, :precision => 5) # => "1.1229 TB" - # 524288000.to_s(:human_size, :precision => 5) # => "500 MB" + # 123.to_s(:human_size) # => 123 Bytes + # 1234.to_s(:human_size) # => 1.21 KB + # 12345.to_s(:human_size) # => 12.1 KB + # 1234567.to_s(:human_size) # => 1.18 MB + # 1234567890.to_s(:human_size) # => 1.15 GB + # 1234567890123.to_s(:human_size) # => 1.12 TB + # 1234567.to_s(:human_size, precision: 2) # => 1.2 MB + # 483989.to_s(:human_size, precision: 2) # => 470 KB + # 1234567.to_s(:human_size, precision: 2, separator: ',') # => 1,2 MB + # 1234567890123.to_s(:human_size, precision: 5) # => "1.1229 TB" + # 524288000.to_s(:human_size, precision: 5) # => "500 MB" # # Human-friendly format: - # 123.to_s(:human) # => "123" - # 1234.to_s(:human) # => "1.23 Thousand" - # 12345.to_s(:human) # => "12.3 Thousand" - # 1234567.to_s(:human) # => "1.23 Million" - # 1234567890.to_s(:human) # => "1.23 Billion" - # 1234567890123.to_s(:human) # => "1.23 Trillion" - # 1234567890123456.to_s(:human) # => "1.23 Quadrillion" - # 1234567890123456789.to_s(:human) # => "1230 Quadrillion" - # 489939.to_s(:human, :precision => 2) # => "490 Thousand" - # 489939.to_s(:human, :precision => 4) # => "489.9 Thousand" - # 1234567.to_s(:human, :precision => 4, - # :significant => false) # => "1.2346 Million" - # 1234567.to_s(:human, :precision => 1, - # :separator => ',', - # :significant => false) # => "1,2 Million" + # 123.to_s(:human) # => "123" + # 1234.to_s(:human) # => "1.23 Thousand" + # 12345.to_s(:human) # => "12.3 Thousand" + # 1234567.to_s(:human) # => "1.23 Million" + # 1234567890.to_s(:human) # => "1.23 Billion" + # 1234567890123.to_s(:human) # => "1.23 Trillion" + # 1234567890123456.to_s(:human) # => "1.23 Quadrillion" + # 1234567890123456789.to_s(:human) # => "1230 Quadrillion" + # 489939.to_s(:human, precision: 2) # => "490 Thousand" + # 489939.to_s(:human, precision: 4) # => "489.9 Thousand" + # 1234567.to_s(:human, precision: 4, + # significant: false) # => "1.2346 Million" + # 1234567.to_s(:human, precision: 1, + # separator: ',', + # significant: false) # => "1,2 Million" def to_formatted_s(format = :default, options = {}) case format when :phone diff --git a/activesupport/lib/active_support/core_ext/numeric/time.rb b/activesupport/lib/active_support/core_ext/numeric/time.rb index 2bf3d1f278..87b9a23aef 100644 --- a/activesupport/lib/active_support/core_ext/numeric/time.rb +++ b/activesupport/lib/active_support/core_ext/numeric/time.rb @@ -8,13 +8,13 @@ class Numeric # These methods use Time#advance for precise date calculations when using from_now, ago, etc. # as well as adding or subtracting their results from a Time object. For example: # - # # equivalent to Time.current.advance(:months => 1) + # # equivalent to Time.current.advance(months: 1) # 1.month.from_now # - # # equivalent to Time.current.advance(:years => 2) + # # equivalent to Time.current.advance(years: 2) # 2.years.from_now # - # # equivalent to Time.current.advance(:months => 4, :years => 5) + # # equivalent to Time.current.advance(months: 4, years: 5) # (4.months + 5.years).from_now # # While these methods provide precise calculation when used as in the examples above, care diff --git a/activesupport/lib/active_support/core_ext/object/blank.rb b/activesupport/lib/active_support/core_ext/object/blank.rb index e238fef5a2..8a5eb4bc93 100644 --- a/activesupport/lib/active_support/core_ext/object/blank.rb +++ b/activesupport/lib/active_support/core_ext/object/blank.rb @@ -43,7 +43,6 @@ class NilClass # +nil+ is blank: # # nil.blank? # => true - # def blank? true end @@ -53,7 +52,6 @@ class FalseClass # +false+ is blank: # # false.blank? # => true - # def blank? true end @@ -63,7 +61,6 @@ class TrueClass # +true+ is not blank: # # true.blank? # => false - # def blank? false end @@ -74,7 +71,6 @@ class Array # # [].blank? # => true # [1,2,3].blank? # => false - # alias_method :blank?, :empty? end @@ -82,8 +78,7 @@ class Hash # A hash is blank if it's empty: # # {}.blank? # => true - # {:key => 'value'}.blank? # => false - # + # { key: 'value' }.blank? # => false alias_method :blank?, :empty? end @@ -94,7 +89,6 @@ class String # ' '.blank? # => true # ' '.blank? # => true # ' something here '.blank? # => false - # def blank? self !~ /[^[:space:]]/ end @@ -105,7 +99,6 @@ class Numeric #:nodoc: # # 1.blank? # => false # 0.blank? # => false - # def blank? false end diff --git a/activesupport/lib/active_support/core_ext/object/duplicable.rb b/activesupport/lib/active_support/core_ext/object/duplicable.rb index f1b755c2c4..9cd7485e2e 100644 --- a/activesupport/lib/active_support/core_ext/object/duplicable.rb +++ b/activesupport/lib/active_support/core_ext/object/duplicable.rb @@ -31,7 +31,6 @@ class NilClass # # nil.duplicable? # => false # nil.dup # => TypeError: can't dup NilClass - # def duplicable? false end @@ -42,7 +41,6 @@ class FalseClass # # false.duplicable? # => false # false.dup # => TypeError: can't dup FalseClass - # def duplicable? false end @@ -53,7 +51,6 @@ class TrueClass # # true.duplicable? # => false # true.dup # => TypeError: can't dup TrueClass - # def duplicable? false end @@ -64,7 +61,6 @@ class Symbol # # :my_symbol.duplicable? # => false # :my_symbol.dup # => TypeError: can't dup Symbol - # def duplicable? false end @@ -75,7 +71,6 @@ class Numeric # # 3.duplicable? # => false # 3.dup # => TypeError: can't dup Fixnum - # def duplicable? false end diff --git a/activesupport/lib/active_support/core_ext/object/to_json.rb b/activesupport/lib/active_support/core_ext/object/to_json.rb index e7dc60a612..83cc8066e7 100644 --- a/activesupport/lib/active_support/core_ext/object/to_json.rb +++ b/activesupport/lib/active_support/core_ext/object/to_json.rb @@ -17,3 +17,11 @@ end end end end + +module Process + class Status + def as_json(options = nil) + { :exitstatus => exitstatus, :pid => pid } + end + end +end diff --git a/activesupport/lib/active_support/core_ext/object/with_options.rb b/activesupport/lib/active_support/core_ext/object/with_options.rb index e058367111..42e388b065 100644 --- a/activesupport/lib/active_support/core_ext/object/with_options.rb +++ b/activesupport/lib/active_support/core_ext/object/with_options.rb @@ -10,16 +10,16 @@ class Object # Without <tt>with_options></tt>, this code contains duplication: # # class Account < ActiveRecord::Base - # has_many :customers, :dependent => :destroy - # has_many :products, :dependent => :destroy - # has_many :invoices, :dependent => :destroy - # has_many :expenses, :dependent => :destroy + # has_many :customers, dependent: :destroy + # has_many :products, dependent: :destroy + # has_many :invoices, dependent: :destroy + # has_many :expenses, dependent: :destroy # end # # Using <tt>with_options</tt>, we can remove the duplication: # # class Account < ActiveRecord::Base - # with_options :dependent => :destroy do |assoc| + # with_options dependent: :destroy do |assoc| # assoc.has_many :customers # assoc.has_many :products # assoc.has_many :invoices @@ -29,14 +29,13 @@ class Object # # It can also be used with an explicit receiver: # - # I18n.with_options :locale => user.locale, :scope => 'newsletter' do |i18n| + # I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n| # subject i18n.t :subject - # body i18n.t :body, :user_name => user.name + # body i18n.t :body, user_name: user.name # end # # <tt>with_options</tt> can also be nested since the call is forwarded to its receiver. # Each nesting level will merge inherited defaults in addition to their own. - # def with_options(options) yield ActiveSupport::OptionMerger.new(self, options) end diff --git a/activesupport/lib/active_support/core_ext/string/filters.rb b/activesupport/lib/active_support/core_ext/string/filters.rb index 8644529806..e05447439a 100644 --- a/activesupport/lib/active_support/core_ext/string/filters.rb +++ b/activesupport/lib/active_support/core_ext/string/filters.rb @@ -24,16 +24,16 @@ class String # # Pass a string or regexp <tt>:separator</tt> to truncate +text+ at a natural break: # - # 'Once upon a time in a world far far away'.truncate(27, :separator => ' ') + # 'Once upon a time in a world far far away'.truncate(27, separator: ' ') # # => "Once upon a time in a..." # - # 'Once upon a time in a world far far away'.truncate(27, :separator => /\s/) + # 'Once upon a time in a world far far away'.truncate(27, separator: /\s/) # # => "Once upon a time in a..." # # The last characters will be replaced with the <tt>:omission</tt> string (defaults to "...") # for a total length not exceeding <tt>length</tt>: # - # 'And they found that many people were sleeping better.'.truncate(25, :omission => '... (continued)') + # 'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)') # # => "And they f... (continued)" def truncate(truncate_at, options = {}) return dup unless length > truncate_at diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index c17d695967..5f85cedcf5 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -3,7 +3,7 @@ require 'active_support/core_ext/kernel/singleton_class' class ERB module Util - HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' } + HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' } JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' } HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+));)/ JSON_ESCAPE_REGEXP = /[&"><]/ @@ -59,19 +59,11 @@ class ERB # # json_escape('{"name":"john","created_at":"2010-04-28T01:39:31Z","id":1}') # # => {name:john,created_at:2010-04-28T01:39:31Z,id:1} - # - # This method is also aliased as +j+, and available as a helper - # in Rails templates: - # - # <%=j @person.to_json %> - # def json_escape(s) result = s.to_s.gsub(JSON_ESCAPE_REGEXP) { |special| JSON_ESCAPE[special] } s.html_safe? ? result.html_safe : result end - alias j json_escape - module_function :j module_function :json_escape end end diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index d0f574f2ba..e3665cd896 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -2,18 +2,12 @@ require 'active_support/duration' require 'active_support/core_ext/time/conversions' require 'active_support/time_with_zone' require 'active_support/core_ext/time/zones' +require 'active_support/core_ext/date_and_time/calculations' class Time + include DateAndTime::Calculations + COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] - DAYS_INTO_WEEK = { - :monday => 0, - :tuesday => 1, - :wednesday => 2, - :thursday => 3, - :friday => 4, - :saturday => 5, - :sunday => 6 - } class << self # Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances @@ -63,29 +57,22 @@ class Time end end - # Tells whether the Time object's time lies in the past - def past? - self < ::Time.current - end - - # Tells whether the Time object's time is today - def today? - to_date == ::Date.current - end - - # Tells whether the Time object's time lies in the future - def future? - self > ::Time.current - end - # Seconds since midnight: Time.now.seconds_since_midnight def seconds_since_midnight to_i - change(:hour => 0).to_i + (usec / 1.0e+6) end - # Returns a new Time where one or more of the elements have been changed according to the +options+ parameter. The time options - # (hour, min, sec, usec) reset cascadingly, so if only the hour is passed, then minute, sec, and usec is set to 0. If the hour and - # minute is passed, then sec and usec is set to 0. + # Returns a new Time where one or more of the elements have been changed according + # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>, + # <tt>:sec</tt>, <tt>:usec</tt>) reset cascadingly, so if only the hour is passed, + # then minute, sec, and usec is set to 0. If the hour and minute is passed, then + # sec and usec is set to 0. The +options+ parameter takes a hash with any of these + # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, + # <tt>:sec</tt>, <tt>:usec</tt>. + # + # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0) + # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0) + # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0) def change(options) new_year = options.fetch(:year, year) new_month = options.fetch(:month, month) @@ -146,116 +133,6 @@ class Time end alias :in :since - # Returns a new Time representing the time a number of specified weeks ago. - def weeks_ago(weeks) - advance(:weeks => -weeks) - end - - # Returns a new Time representing the time a number of specified months ago - def months_ago(months) - advance(:months => -months) - end - - # Returns a new Time representing the time a number of specified months in the future - def months_since(months) - advance(:months => months) - end - - # Returns a new Time representing the time a number of specified years ago - def years_ago(years) - advance(:years => -years) - end - - # Returns a new Time representing the time a number of specified years in the future - def years_since(years) - advance(:years => years) - end - - # Short-hand for years_ago(1) - def prev_year - years_ago(1) - end - alias_method :last_year, :prev_year - - # Short-hand for years_since(1) - def next_year - years_since(1) - end - - # Short-hand for months_ago(1) - def prev_month - months_ago(1) - end - alias_method :last_month, :prev_month - - # Short-hand for months_since(1) - def next_month - months_since(1) - end - - # Short-hand for months_ago(3) - def prev_quarter - months_ago(3) - end - alias_method :last_quarter, :prev_quarter - - # Short-hand for months_since(3) - def next_quarter - months_since(3) - end - - # Returns number of days to start of this week, week starts on start_day (default is :monday). - def days_to_week_start(start_day = :monday) - start_day_number = DAYS_INTO_WEEK[start_day] - current_day_number = wday != 0 ? wday - 1 : 6 - days_span = current_day_number - start_day_number - - days_span >= 0 ? days_span : 7 + days_span - end - - # Returns a new Time representing the "start" of this week, week starts on start_day (default is :monday, i.e. Monday, 0:00). - def beginning_of_week(start_day = :monday) - days_to_start = days_to_week_start(start_day) - (self - days_to_start.days).midnight - end - alias :at_beginning_of_week :beginning_of_week - - # Returns a new +Date+/+DateTime+ representing the start of this week. Week is - # assumed to start on a Monday. +DateTime+ objects have their time set to 0:00. - def monday - beginning_of_week - end - - # Returns a new Time representing the end of this week, week starts on start_day (default is :monday, i.e. end of Sunday). - def end_of_week(start_day = :monday) - days_to_end = 6 - days_to_week_start(start_day) - (self + days_to_end.days).end_of_day - end - alias :at_end_of_week :end_of_week - - # Returns a new +Date+/+DateTime+ representing the end of this week. Week is - # assumed to start on a Monday. +DateTime+ objects have their time set to 23:59:59. - def sunday - end_of_week - end - - # Returns a new Time representing the start of the given day in the previous week (default is :monday). - def prev_week(day = :monday) - ago(1.week). - beginning_of_week. - since(DAYS_INTO_WEEK[day].day). - change(:hour => 0) - end - alias_method :last_week, :prev_week - - # Returns a new Time representing the start of the given day in next week (default is :monday). - def next_week(day = :monday) - since(1.week). - beginning_of_week. - since(DAYS_INTO_WEEK[day].day). - change(:hour => 0) - end - # Returns a new Time representing the start of the day (0:00) def beginning_of_day #(self - seconds_since_midnight).change(:usec => 0) @@ -290,77 +167,14 @@ class Time ) end - # Returns a new Time representing the start of the month (1st of the month, 0:00) - def beginning_of_month - #self - ((self.mday-1).days + self.seconds_since_midnight) - change(:day => 1, :hour => 0) - end - alias :at_beginning_of_month :beginning_of_month - - # Returns a new Time representing the end of the month (end of the last day of the month) - def end_of_month - #self - ((self.mday-1).days + self.seconds_since_midnight) - last_day = ::Time.days_in_month(month, year) - change( - :day => last_day, - :hour => 23, - :min => 59, - :sec => 59, - :usec => Rational(999999999, 1000) - ) - end - alias :at_end_of_month :end_of_month - - # Returns a new Time representing the start of the quarter (1st of january, april, july, october, 0:00) - def beginning_of_quarter - first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month } - beginning_of_month.change(:month => first_quarter_month) - end - alias :at_beginning_of_quarter :beginning_of_quarter - - # Returns a new Time representing the end of the quarter (end of the last day of march, june, september, december) - def end_of_quarter - last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month } - beginning_of_month.change(:month => last_quarter_month).end_of_month - end - alias :at_end_of_quarter :end_of_quarter - - # Returns a new Time representing the start of the year (1st of january, 0:00) - def beginning_of_year - change(:month => 1, :day => 1, :hour => 0) - end - alias :at_beginning_of_year :beginning_of_year - - # Returns a new Time representing the end of the year (end of the 31st of december) - def end_of_year - change( - :month => 12, - :day => 31, - :hour => 23, - :min => 59, - :sec => 59, - :usec => Rational(999999999, 1000) - ) - end - alias :at_end_of_year :end_of_year - - # Convenience method which returns a new Time representing the time 1 day ago - def yesterday - advance(:days => -1) - end - - # Convenience method which returns a new Time representing the time 1 day since the instance time - def tomorrow - advance(:days => 1) - end - # Returns a Range representing the whole day of the current time. def all_day beginning_of_day..end_of_day end - # Returns a Range representing the whole week of the current time. Week starts on start_day (default is :monday, i.e. end of Sunday). - def all_week(start_day = :monday) + # Returns a Range representing the whole week of the current time. + # Week starts on start_day, default is <tt>Date.week_start</tt> or <tt>config.week_start</tt> when set. + def all_week(start_day = Date.beginning_of_week) beginning_of_week(start_day)..end_of_week(start_day) end diff --git a/activesupport/lib/active_support/core_ext/time/conversions.rb b/activesupport/lib/active_support/core_ext/time/conversions.rb index 10ca26acf2..48654eb1cc 100644 --- a/activesupport/lib/active_support/core_ext/time/conversions.rb +++ b/activesupport/lib/active_support/core_ext/time/conversions.rb @@ -23,17 +23,17 @@ class Time # # This method is aliased to <tt>to_s</tt>. # - # time = Time.now # => Thu Jan 18 06:10:17 CST 2007 + # time = Time.now # => Thu Jan 18 06:10:17 CST 2007 # - # time.to_formatted_s(:time) # => "06:10" - # time.to_s(:time) # => "06:10" + # time.to_formatted_s(:time) # => "06:10" + # time.to_s(:time) # => "06:10" # - # time.to_formatted_s(:db) # => "2007-01-18 06:10:17" - # time.to_formatted_s(:number) # => "20070118061017" - # time.to_formatted_s(:short) # => "18 Jan 06:10" - # time.to_formatted_s(:long) # => "January 18, 2007 06:10" - # time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10" - # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600" + # time.to_formatted_s(:db) # => "2007-01-18 06:10:17" + # time.to_formatted_s(:number) # => "20070118061017" + # time.to_formatted_s(:short) # => "18 Jan 06:10" + # time.to_formatted_s(:long) # => "January 18, 2007 06:10" + # time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10" + # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600" # # == Adding your own time formats to +to_formatted_s+ # You can add your own formats to the Time::DATE_FORMATS hash. @@ -42,7 +42,7 @@ class Time # # # config/initializers/time_formats.rb # Time::DATE_FORMATS[:month_and_year] = '%B %Y' - # Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") } + # Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") } def to_formatted_s(format = :default) if formatter = DATE_FORMATS[format] formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter) @@ -55,8 +55,8 @@ class Time # Returns the UTC offset as an +HH:MM formatted string. # - # Time.local(2000).formatted_offset # => "-06:00" - # Time.local(2000).formatted_offset(false) # => "-0600" + # Time.local(2000).formatted_offset # => "-06:00" + # Time.local(2000).formatted_offset(false) # => "-0600" def formatted_offset(colon = true, alternate_utc_string = nil) utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon) end diff --git a/activesupport/lib/active_support/core_ext/time/zones.rb b/activesupport/lib/active_support/core_ext/time/zones.rb index 37bc3fae24..139d48f59c 100644 --- a/activesupport/lib/active_support/core_ext/time/zones.rb +++ b/activesupport/lib/active_support/core_ext/time/zones.rb @@ -76,8 +76,8 @@ class Time # Returns the simultaneous time in <tt>Time.zone</tt>. # - # Time.zone = 'Hawaii' # => 'Hawaii' - # Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # Time.zone = 'Hawaii' # => 'Hawaii' + # Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00 # # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone # instead of the operating system's time zone. @@ -85,7 +85,7 @@ class Time # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument, # and the conversion will be based on that zone instead of <tt>Time.zone</tt>. # - # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00 + # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00 def in_time_zone(zone = ::Time.zone) if zone ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone)) |