Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is something like 30.seconds.ago implemented?

I found this question here.

And really curious to know the technical explanation of how something like 30.seconds.ago is implemented in Rails.

Method chaining? Numeric usage as per: http://api.rubyonrails.org/classes/Numeric.html#method-i-seconds .

What else?

like image 724
psharma Avatar asked Nov 10 '15 20:11

psharma


Video Answer


1 Answers

Here is the implementation of the seconds:

  def seconds
    ActiveSupport::Duration.new(self, [[:seconds, self]])
  end

And, here is the implementation of the 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

And, here is the implementation of the sum method that's used inside the ago:

  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

To understand it fully, you should follow the method calls and look for their implementations in the Rails source code like I showed you just now.

One easy way to find a method definition inside Rails code base is to use source_location in your Rails console:

> 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]
like image 86
K M Rakibul Islam Avatar answered Oct 05 '22 05:10

K M Rakibul Islam