在Ruby表达式中' - '后留空的效果

时间:2014-02-07 13:24:10

标签: ruby-on-rails ruby date math

今天我在Rails控制台上尝试了一些事情,发生了这种情况,

2.0.0p247 :009 > Date.today -29.days
 => Fri, 07 Feb 2014 
2.0.0p247 :010 > Date.today - 29.days
 => Thu, 09 Jan 2014 

我很困惑。我可以看到我遗漏了一些基本的东西。但它只是引起我的注意!任何人都可以解释为什么会这样吗?

2 个答案:

答案 0 :(得分:4)

实际发生的是:

Date.today(-29.days) # => Fri, 07 Feb 2014

today有一个名为start的可选参数,默认为Date::ITALY

  

作为朱利安的日历改革(开始)日的可选参数   天数,应该是2298874到2426355或 - / + oo。默认   值是Date :: ITALY(2299161 = 1582-10-15)。

-29.days传递给today显然没效果。

鉴于:

Date.today + -29.days # => Thu, 09 Jan 2014

与以下内容相同:

Date.today - 29.days # => Thu, 09 Jan 2014

答案 1 :(得分:2)

Ruby中的Fixnum#days方法在ActiveSupport中的Rails库中定义。更具体地说,它在'active_support / core_ext / numeric / time`模块中定义

只需在控制台中加载ActiveSupport

> require 'active_support'
true
> require 'active_support/core_ext'
true

> 29.days
=> 2505600

> -29.days
=> -2505600

方法days的代码如下所示:

def days
  ActiveSupport::Duration.new(self * 24.hours, [[:days, self]])
end

在这种情况下,self对象是29 or -29。这将乘以2505600这是一个合理的计算,并将返回数字29代表的秒数。

考虑到这一点,在第一次计算中,您只是将两个对象传递给控制台输入,第一个是Date对象,第二个是数字。与发送以下内容类似:

> puts "test"

也就是说,-29.days作为参数传递给Date.today返回的对象。 Date.today接受一个指定日历开始日期的参数。 Refer to this answer to know the accepted days。如果传递了任何未识别的参数,则使用默认的开始日期(即Date :: GREGORIAN)

> Date.today
=> Thu, 09 Feb 2014

> Date.today Date::JULIAN
=> Fri, 25 Jan 2014

因此,Ruby会检查您是否传入了有效的开始日期常量,并确定了开始日期。因此,在运行第一个命令时,您仍然可以获得今天的日期作为答案。

第二个命令只是减去一个Date对象,另一个对象被Ruby理解为你想要从今天的日期中减去的秒数。在这两种情况下,29.days都会在内部转换为秒数。

希望有所帮助。