新手问题 [已解决] 请教社区活动 PPT 问题: How to avoid 1.hour.hour?

huopo125 · 2014年08月17日 · 最后由 huopo125 回复于 2014年08月18日 · 2052 次阅读

无法看懂是如何避免此种操作的,求解...

class Duration
  def inspect
    value = @proxy
    parts = %w[days hours minutes seconds].inject([]) do |units, unit|
      if value >= 1.send(unit)
        quotient, value = value.divmod 1.send(unit)
        units + [[quotient, unit]]
      else
        units
      end
    end
    parts.map! {|value, unit| "#{value} #{value == 1 ? unit.chop : unit}" }
    parts.join(', ')
  end
end

上面的代码应该只是显示 format 后的时间的吧。 比如 25.hours.inspect #=> 1 day, 1 hour 原理是除法取余数然后再处理结果

另外 Rails 本身并没有措施避免1.hour.hour, (4.1.1)

Loading development environment (Rails 4.1.1)
2.1.1 :001 > 1.hour.hour
 => 12960000 seconds 
2.1.1 :002 > 1.hour
 => 3600 seconds 

因为 ActiveSupport::Duration 并没有定义 hour method. 所以 Duration#hour 会通过 method_missing 调用 Fixnum#hour

def method_missing(method, *args, &block) #:nodoc:
  value.send(method, *args, &block)
end

要避免这种调用,可以在 ActiveSupport::Duration 定义 hour method, raise exception.

谢谢解答!当时也奇怪,Rails 中并未不允许此种写法,一时感到困惑。解答的很完美,再次感谢!

需要 登录 后方可回复, 如果你还没有账号请 注册新账号