繁体   English   中英

在使用Ruby on Rails ActiveSupport Time Extensions进行元编程时,为什么会出现这种差异?

[英]Why do I get this discrepancy when doing meta-programming with Ruby on Rails ActiveSupport Time Extensions?

我在玩ActiveSupport Time Core Extensions(rails 4.1.2)。 这是我遇到的一个问题。

为什么会出现这种差异?

2.0.0-p451 :011 >   Time.zone.now
=> Wed, 23 Jul 2014 16:38:21 EDT -04:00 

2.0.0-p451 :012 > 4.months.ago
=> Sun, 23 Mar 2014 16:38:25 EDT -04:00 

2.0.0-p451 :013 > 4.send(:months).send(:ago)
DEPRECATION WARNING: Calling #ago or #until on a number (e.g. 5.ago) is deprecated and  
will be removed in the future, use 5.seconds.ago instead. (called from irb_binding at 
(irb):13)
=> Tue, 25 Mar 2014 16:38:35 EDT -04:00 

我在最后一条语句中看到一个问题:2天后4.months.ago返回。 此外,我收到警告,而致电4.months.ago4.months.ago收到警告。

有人知道为什么吗?

4.months返回的对象是ActiveSupport::Duration ,它继承自ActiveSupport::ProxyObjectBasicObject BasicObject行为不像其他对象,在这种特殊情况下,与BasicObject没有send方法相关的是:

[7] pry(main)> BasicObject.new.send
NoMethodError: undefined method `send' for #<BasicObject:0x007f9e23997910>

ActiveSupport::Duration有一个method_missing的实现,该实现将未知方法传递给基础数字对象。

因此,当您调用4.send(:months).send(:ago) ,您会将ago方法调用发送到基础Fixnum而不是ActiveSupport::Duration对象。

这打破了months计算,因为将4.months转换为数字4.months变为120天:

[9] pry(main)> 4.months.to_i
=> 10368000
[10] pry(main)> 120.days.to_i
=> 10368000

编辑:您可以使用__send__方法解决此问题,但这并不是真正的首选方法:

[15] pry(main)> 4.months.__send__(:ago)
=> Sun, 23 Mar 2014 21:14:20 UTC +00:00
[16] pry(main)> 4.months.ago
=> Sun, 23 Mar 2014 21:14:27 UTC +00:00

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM