fatuhoku fatuhoku - 1 month ago 5
Ruby Question

How can I override the .. and ... operators of Ruby Ranges to accept Float::INFINITY?

I want to override the

..
and
...
operators in Ruby's
Range
.

Reason is, I'm working with infinite date ranges in the database. If you pull an
infinty
datetime out of Postgres, you get a
Float::INFINITY
in Ruby.

The problem with this is, I cannot use
Float::INFINITY
as the end of a range:

Date.today...Float::INFINITY
=> Wed, 02 Nov 2016...Infinity

DateTime.now...Float::INFINITY
# ArgumentError: bad value for range

Time.now...Float::INFINITY
# ArgumentError: bad value for range


... yet I use
..
and
...
syntax quite often in my code.

To even be able to construct the range, you need to use
DateTime::Infinity.new
instead:

Date.today...DateTime::Infinity.new
=> Wed, 02 Nov 2016...#<Date::Infinity:0x007fd82348c698 @d=1>

DateTime.now...DateTime::Infinity.new
=> Wed, 02 Nov 2016 12:57:07 +0000...#<Date::Infinity:0x007fd82348c698 @d=1>

Time.now...DateTime::Infinity.new
=> 2016-11-02 12:57:33 +0000...#<Date::Infinity:0x007fd82348c698 @d=1>


But I would need to do the the
Float::INFINITY
->
DateTime::Infinity.new
conversion every time:

model.start_time...convert_infinity(model.end_time)


Is there a way I can override the
..
and
...
operators so that I can incorporate the conversion function and keep the syntactic sugar?

Answer

I don't think that what you want to do is a correct way of solving such issue.

What I would suggest instead, is to simply override the end_date method in model:

def end_date
  super == Float::INFINITY ? DateTime::Infinity.new : super
end

This basically says if end_date in db is Float::INFINITY return DateTime::Infinity.new as end_date, otherwise return what's in database.