30.seconds.ago 之类的东西是如何实现的?
How is something like 30.seconds.ago implemented?
我找到了这个问题 here。
并且真的很想知道在 Rails 中如何实现类似 30.seconds.ago
的技术解释。
方法链接? Numeric
用法如下:
http://api.rubyonrails.org/classes/Numeric.html#method-i-seconds。
还有什么?
Here是seconds
:
的实现
def seconds
ActiveSupport::Duration.new(self, [[:seconds, self]])
end
并且,here是ago
的实现:
# Calculates a new Time or Date that is as far in the past
# as this Duration represents.
def ago(time = ::Time.current)
sum(-1, time)
end
并且,here 是 ago
中使用的 sum
方法的实现:
def sum(sign, time = ::Time.current) #:nodoc:
parts.inject(time) do |t,(type,number)|
if t.acts_like?(:time) || t.acts_like?(:date)
if type == :seconds
t.since(sign * number)
else
t.advance(type => sign * number)
end
else
raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
end
end
end
要完全理解它,您应该按照我刚才向您展示的方法调用并在 Rails 源代码中查找它们的实现。
在 Rails 代码库中查找方法定义的一种简单方法是在 Rails 控制台中使用 source_location
:
> 30.method(:seconds).source_location
# => ["/Users/rislam/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/core_ext/numeric/time.rb", 19]
> 30.seconds.method(:ago).source_location
# => ["/Users/rislam/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/duration.rb", 108]
我找到了这个问题 here。
并且真的很想知道在 Rails 中如何实现类似 30.seconds.ago
的技术解释。
方法链接? Numeric
用法如下:
http://api.rubyonrails.org/classes/Numeric.html#method-i-seconds。
还有什么?
Here是seconds
:
def seconds
ActiveSupport::Duration.new(self, [[:seconds, self]])
end
并且,here是ago
的实现:
# Calculates a new Time or Date that is as far in the past
# as this Duration represents.
def ago(time = ::Time.current)
sum(-1, time)
end
并且,here 是 ago
中使用的 sum
方法的实现:
def sum(sign, time = ::Time.current) #:nodoc:
parts.inject(time) do |t,(type,number)|
if t.acts_like?(:time) || t.acts_like?(:date)
if type == :seconds
t.since(sign * number)
else
t.advance(type => sign * number)
end
else
raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
end
end
end
要完全理解它,您应该按照我刚才向您展示的方法调用并在 Rails 源代码中查找它们的实现。
在 Rails 代码库中查找方法定义的一种简单方法是在 Rails 控制台中使用 source_location
:
> 30.method(:seconds).source_location
# => ["/Users/rislam/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/core_ext/numeric/time.rb", 19]
> 30.seconds.method(:ago).source_location
# => ["/Users/rislam/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/duration.rb", 108]