Skip to content

Commit

Permalink
Merge pull request #19878 from pabloh/replace_alias_chains_with_prepend
Browse files Browse the repository at this point in the history
Replace use of alias chains with prepend at core_ext/date and core_ext/time
  • Loading branch information
rafaelfranca committed May 29, 2015
2 parents 9ff901b + bbe7b7f commit 6e83a13
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 89 deletions.
34 changes: 2 additions & 32 deletions activesupport/lib/active_support/core_ext/date/calculations.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
require 'date'
require 'active_support/duration'
require 'active_support/core_ext/object/acts_like'
require 'active_support/core_ext/date/zones'
require 'active_support/core_ext/date/operators'
require 'active_support/core_ext/time/zones'
require 'active_support/core_ext/date_and_time/calculations'

class Date
include DateAndTime::Calculations
prepend ActiveSupport::DateOperators

class << self
attr_accessor :beginning_of_week_default
Expand Down Expand Up @@ -85,26 +86,6 @@ def end_of_day
end
alias :at_end_of_day :end_of_day

def plus_with_duration(other) #:nodoc:
if ActiveSupport::Duration === other
other.since(self)
else
plus_without_duration(other)
end
end
alias_method :plus_without_duration, :+
alias_method :+, :plus_with_duration

def minus_with_duration(other) #:nodoc:
if ActiveSupport::Duration === other
plus_with_duration(-other)
else
minus_without_duration(other)
end
end
alias_method :minus_without_duration, :-
alias_method :-, :minus_with_duration

# Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
# any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
def advance(options)
Expand All @@ -129,15 +110,4 @@ def change(options)
options.fetch(:day, day)
)
end

# Allow Date to be compared with Time by converting to DateTime and relying on the <=> from there.
def compare_with_coercion(other)
if other.is_a?(Time)
self.to_datetime <=> other
else
compare_without_coercion(other)
end
end
alias_method :compare_without_coercion, :<=>
alias_method :<=>, :compare_with_coercion
end
16 changes: 16 additions & 0 deletions activesupport/lib/active_support/core_ext/date/operators.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require 'active_support/core_ext/date_and_time/with_duration'

module ActiveSupport
module DateOperators # :nodoc:
include DateAndTime::WithDuration

# Allow Date to be compared with Time by converting to DateTime and relying on the <=> from there.
def <=>(other)
if other.is_a?(Time)
self.to_datetime <=> other
else
super
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'active_support/duration'

module ActiveSupport
module DateAndTime
module WithDuration #:nodoc:
def +(other) #:nodoc:
if ActiveSupport::Duration === other
other.since(self)
else
super
end
end

def -(other) #:nodoc:
if ActiveSupport::Duration === other
self + (-other)
else
super
end
end
end
end
end
59 changes: 2 additions & 57 deletions activesupport/lib/active_support/core_ext/time/calculations.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,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/time/operators'
require 'active_support/core_ext/date_and_time/calculations'

class Time
include DateAndTime::Calculations
prepend ActiveSupport::TimeOperators

COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

Expand Down Expand Up @@ -212,60 +213,4 @@ def end_of_minute
def all_day
beginning_of_day..end_of_day
end

def plus_with_duration(other) #:nodoc:
if ActiveSupport::Duration === other
other.since(self)
else
plus_without_duration(other)
end
end
alias_method :plus_without_duration, :+
alias_method :+, :plus_with_duration

def minus_with_duration(other) #:nodoc:
if ActiveSupport::Duration === other
other.until(self)
else
minus_without_duration(other)
end
end
alias_method :minus_without_duration, :-
alias_method :-, :minus_with_duration

# Time#- can also be used to determine the number of seconds between two Time instances.
# We're layering on additional behavior so that ActiveSupport::TimeWithZone instances
# are coerced into values that Time#- will recognize
def minus_with_coercion(other)
other = other.comparable_time if other.respond_to?(:comparable_time)
other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
end
alias_method :minus_without_coercion, :-
alias_method :-, :minus_with_coercion

# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
# can be chronologically compared with a Time
def compare_with_coercion(other)
# we're avoiding Time#to_datetime and Time#to_time because they're expensive
if other.class == Time
compare_without_coercion(other)
elsif other.is_a?(Time)
compare_without_coercion(other.to_time)
else
to_datetime <=> other
end
end
alias_method :compare_without_coercion, :<=>
alias_method :<=>, :compare_with_coercion

# Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances
# can be eql? to an equivalent Time
def eql_with_coercion(other)
# if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison
other = other.comparable_time if other.respond_to?(:comparable_time)
eql_without_coercion(other)
end
alias_method :eql_without_coercion, :eql?
alias_method :eql?, :eql_with_coercion

end
36 changes: 36 additions & 0 deletions activesupport/lib/active_support/core_ext/time/operators.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'active_support/core_ext/date_and_time/with_duration'

module ActiveSupport
module TimeOperators # :nodoc:
include DateAndTime::WithDuration

# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
# can be chronologically compared with a Time
def <=>(other)
# we're avoiding Time#to_datetime and Time#to_time because they're expensive
if other.class == Time
super
elsif other.is_a?(Time)
super(other.to_time)
else
to_datetime <=> other
end
end

# Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances
# can be eql? to an equivalent Time
def eql?(other)
# if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison
other = other.comparable_time if other.respond_to?(:comparable_time)
super
end

# Time#- can also be used to determine the number of seconds between two Time instances.
# We're layering on additional behavior so that ActiveSupport::TimeWithZone instances
# are coerced into values that Time#- will recognize
def -(other)
other = other.comparable_time if other.respond_to?(:comparable_time)
other.is_a?(DateTime) ? to_f - other.to_f : super
end
end
end

0 comments on commit 6e83a13

Please sign in to comment.