[英]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.ago
时4.months.ago
收到警告。
有人知道为什么吗?
4.months
返回的对象是ActiveSupport::Duration
,它继承自ActiveSupport::ProxyObject
→ BasicObject
。 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.