如何覆盖Ruby Ranges的..和...运算符以接受Float :: INFINITY?

时间:2016-11-02 13:00:12

标签: ruby-on-rails ruby postgresql ruby-on-rails-4.2

我想覆盖Ruby的..中的...Range运算符。

原因是,我正在使用数据库中的无限日期范围。如果从Postgres中提取infinty日期时间,则会在Ruby中获得Float::INFINITY

问题是,我不能使用Float::INFINITY作为范围的结尾:

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

...但我在代码中经常使用.....语法。

为了能够构建范围,您需要使用DateTime::Infinity.new代替:

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> 

但我需要做Float::INFINITY - &gt;每次DateTime::Infinity.new次转化:

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

有没有办法可以覆盖.....运算符,以便我可以合并转换函数并保留语法糖?

2 个答案:

答案 0 :(得分:3)

我认为你想做的不是解决这个问题的正确方法。

我建议的是简单地覆盖模型中的end_date方法:

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

这基本上说如果db中的end_date Float::INFINITY返回DateTime::Infinity.newend_date,否则返回数据库中的内容。

答案 1 :(得分:1)

Ruby 2.6引入了endless range,可以通过这种方式使用它,例如:

(DateTime.now..)
(DateTime.now...)

这为回答此问题提供了一种新方法。希望对某人有用!