Class: Monotime::Duration

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/monotime/duration.rb

Overview

A type representing a span of time in nanoseconds.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(nanos = 0) ⇒ Duration

Create a new Duration of a specified number of nanoseconds, zero by default.

Users are strongly advised to use #from_nanos instead.

Parameters:

  • nanos (Integer) (defaults to: 0)

See Also:

  • #from_nanos


15
16
17
18
# File 'lib/monotime/duration.rb', line 15

def initialize(nanos = 0)
  @ns = Integer(nanos)
  freeze
end

Class Method Details

.from_micros(micros) ⇒ Duration Also known as: micros

Generate a new Duration measuring the given number of microseconds.

Parameters:

  • micros (Numeric)

Returns:



45
46
47
# File 'lib/monotime/duration.rb', line 45

def from_micros(micros)
  new(Integer(micros * 1_000))
end

.from_millis(millis) ⇒ Duration Also known as: millis

Generate a new Duration measuring the given number of milliseconds.

Parameters:

  • millis (Numeric)

Returns:



35
36
37
# File 'lib/monotime/duration.rb', line 35

def from_millis(millis)
  new(Integer(millis * 1_000_000))
end

.from_nanos(nanos) ⇒ Duration Also known as: nanos

Generate a new Duration measuring the given number of nanoseconds.

Parameters:

  • nanos (Numeric)

Returns:



55
56
57
# File 'lib/monotime/duration.rb', line 55

def from_nanos(nanos)
  new(Integer(nanos))
end

.from_secs(secs) ⇒ Duration Also known as: secs

Generate a new Duration measuring the given number of seconds.

Parameters:

  • secs (Numeric)

Returns:



25
26
27
# File 'lib/monotime/duration.rb', line 25

def from_secs(secs)
  new(Integer(secs * 1_000_000_000))
end

.measureDuration

Return a Duration measuring the elapsed time of the yielded block.

Examples:

Duration.measure { sleep(0.5) }.to_s # => "512.226109ms"

Returns:



67
68
69
# File 'lib/monotime/duration.rb', line 67

def measure
  Instant.now.tap { yield }.elapsed
end

.with_measureObject, Duration

Return the result of the yielded block alongside a Duration.

Examples:

Duration.with_measure { "bloop" } # => ["bloop", #<Monotime::Duration: ...>]

Returns:



77
78
79
80
81
# File 'lib/monotime/duration.rb', line 77

def with_measure
  start = Instant.now
  ret = yield
  [ret, start.elapsed]
end

Instance Method Details

#*(other) ⇒ Duration

Multiply this duration by a Numeric.

Examples:

(Duration.from_secs(10) * 2).to_s # => "20s"

Parameters:

  • (Numeric)

Returns:



130
131
132
# File 'lib/monotime/duration.rb', line 130

def *(other)
  Duration.new(to_nanos * other)
end

#+(other) ⇒ Duration

Add another Duration or #to_nanos-coercible object to this one, returning a new Duration.

Examples:

(Duration.from_secs(10) + Duration.from_secs(5)).to_s # => "15s"

Parameters:

Returns:

Raises:

  • (TypeError)


92
93
94
95
96
# File 'lib/monotime/duration.rb', line 92

def +(other)
  raise TypeError, 'Not one of: [Duration, #to_nanos]' unless other.respond_to?(:to_nanos)

  Duration.new(to_nanos + other.to_nanos)
end

#-(other) ⇒ Duration

Subtract another Duration or #to_nanos-coercible object from this one, returning a new Duration.

Examples:

(Duration.from_secs(10) - Duration.from_secs(5)).to_s # => "5s"

Parameters:

Returns:

Raises:

  • (TypeError)


106
107
108
109
110
# File 'lib/monotime/duration.rb', line 106

def -(other)
  raise TypeError, 'Not one of: [Duration, #to_nanos]' unless other.respond_to?(:to_nanos)

  Duration.new(to_nanos - other.to_nanos)
end

#-@Duration

Unary minus: make a positive Duration negative, and vice versa.

Examples:

-Duration.from_secs(-1).to_s # => "1s"
-Duration.from_secs(1).to_s  # => "-1s"

Returns:



141
142
143
# File 'lib/monotime/duration.rb', line 141

def -@
  Duration.new(-to_nanos)
end

#/(other) ⇒ Duration

Divide this duration by a Numeric.

Examples:

(Duration.from_secs(10) / 2).to_s # => "5s"

Parameters:

  • (Numeric)

Returns:



119
120
121
# File 'lib/monotime/duration.rb', line 119

def /(other)
  Duration.new(to_nanos / other)
end

#<=>(other) ⇒ -1, ...

Compare the value of this Duration with another, or any #to_nanos-coercible object, or nil if not comparable.

Parameters:

Returns:

  • (-1, 0, 1, nil)


163
164
165
# File 'lib/monotime/duration.rb', line 163

def <=>(other)
  to_nanos <=> other.to_nanos if other.respond_to?(:to_nanos)
end

#==(other) ⇒ Boolean

Compare the equality of the value of this Duration with another, or any #to_nanos-coercible object, or nil if not comparable.

Parameters:

Returns:

  • (Boolean)


172
173
174
# File 'lib/monotime/duration.rb', line 172

def ==(other)
  other.respond_to?(:to_nanos) && to_nanos == other.to_nanos
end

#absDuration

Return a Duration that’s absolute (positive).

Examples:

Duration.from_secs(-1).abs.to_s # => "1s"
Duration.from_secs(1).abs.to_s  # => "1s"

Returns:



152
153
154
155
156
# File 'lib/monotime/duration.rb', line 152

def abs
  return self if positive? || zero?

  Duration.new(to_nanos.abs)
end

#eql?(other) ⇒ Boolean

Check equality of the value and type of this Duration with another.

Parameters:

Returns:

  • (Boolean)


180
181
182
# File 'lib/monotime/duration.rb', line 180

def eql?(other)
  other.is_a?(Duration) && to_nanos == other.to_nanos
end

#hashInteger

Generate a hash for this type and value.

Returns:

  • (Integer)


187
188
189
# File 'lib/monotime/duration.rb', line 187

def hash
  self.class.hash ^ to_nanos.hash
end

#negative?Boolean

Return true if this Duration is negative.

Returns:

  • (Boolean)


237
238
239
# File 'lib/monotime/duration.rb', line 237

def negative?
  to_nanos.negative?
end

#nonzero?Boolean

Return true if this Duration is non-zero.

Returns:

  • (Boolean)


251
252
253
# File 'lib/monotime/duration.rb', line 251

def nonzero?
  to_nanos.nonzero?
end

#positive?Boolean

Return true if this Duration is positive.

Returns:

  • (Boolean)


230
231
232
# File 'lib/monotime/duration.rb', line 230

def positive?
  to_nanos.positive?
end

#sleepInteger

Sleep for the duration of this Duration. Equivalent to Kernel.sleep(duration.to_secs).

Examples:

Duration.from_secs(1).sleep  # => 1
Duration.from_secs(-1).sleep # => raises NotImplementedError

Returns:

  • (Integer)

Raises:

  • (NotImplementedError)

    negative Duration sleeps are not yet supported.

See Also:



265
266
267
268
269
# File 'lib/monotime/duration.rb', line 265

def sleep
  raise NotImplementedError, 'time travel module missing' if negative?

  Kernel.sleep(to_secs)
end

#to_microsFloat Also known as: micros

Return this Duration in microseconds.

Returns:

  • (Float)


212
213
214
# File 'lib/monotime/duration.rb', line 212

def to_micros
  to_nanos / 1_000.0
end

#to_millisFloat Also known as: millis

Return this Duration in milliseconds.

Returns:

  • (Float)


203
204
205
# File 'lib/monotime/duration.rb', line 203

def to_millis
  to_nanos / 1_000_000.0
end

#to_nanosInteger Also known as: nanos

Return this Duration in nanoseconds.

Returns:

  • (Integer)


221
222
223
# File 'lib/monotime/duration.rb', line 221

def to_nanos
  @ns
end

#to_s(precision = 9) ⇒ String

Format this Duration into a human-readable string, with a given number of decimal places.

The exact format is subject to change, users with specific requirements are encouraged to use their own formatting methods.

Examples:

Duration.from_nanos(100).to_s  # => "100ns"
Duration.from_micros(100).to_s # => "100μs"
Duration.from_millis(100).to_s # => "100ms"
Duration.from_secs(100).to_s   # => "100s"
Duration.from_nanos(1234567).to_s # => "1.234567ms"
Duration.from_nanos(1234567).to_s(2) # => "1.23ms"

Parameters:

  • precision (Integer) (defaults to: 9)

    the maximum number of decimal places

Returns:

  • (String)


296
297
298
299
300
301
302
303
304
305
# File 'lib/monotime/duration.rb', line 296

def to_s(precision = 9)
  precision = Integer(precision).abs
  div, unit = DIVISORS.find { |d, _| to_nanos.abs >= d }

  if div.zero?
    format('%d%s', to_nanos, unit)
  else
    format("%#.#{precision}f", to_nanos / div).sub(/\.?0*\z/, '') << unit
  end
end

#to_secsFloat Also known as: secs

Return this Duration in seconds.

Returns:

  • (Float)


194
195
196
# File 'lib/monotime/duration.rb', line 194

def to_secs
  to_nanos / 1_000_000_000.0
end

#zero?Boolean

Return true if this Duration is zero.

Returns:

  • (Boolean)


244
245
246
# File 'lib/monotime/duration.rb', line 244

def zero?
  to_nanos.zero?
end