monotime 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a97344679471a970a324027b84b560faf9dfc9597c0937094de1486cc0da602
4
- data.tar.gz: 35d55277a3181f0033939263122296b3a5328c5cc1605722644dd21aa9305ac1
3
+ metadata.gz: d77cca7907b76e8276296abc382f10612e7879605f7472ab46e4b26c9594426d
4
+ data.tar.gz: d4d1284f11de89438125a3e28e4686bdde6a78cf02a431d3eb57e861e7345613
5
5
  SHA512:
6
- metadata.gz: 29d7c0fb1aa092127f1a1a3036552466d9f6ea83d337fa3c9ffda0e88d3b5fb4ca996f81c828701a2a1bee4bf44d8c6392395298ac9f257034b3b71b8d0437b3
7
- data.tar.gz: bd3bef852b6d5b25810091e0ee7452e60e03a5cd25cc5577e25760452804d3d201cfc05efd2dcf19d91680ff6bdacbd93b9428473def942ac3c024aea4675c9d
6
+ metadata.gz: 4975756b4d469b02437d7ad45216eef58d5e20b3675f6c725c64d1b8d1da3518c5eec89fc98cbc1d9d0e6238665232e837415783726132b757cf2e19ab2ef4fc
7
+ data.tar.gz: cfe8ffd03b80d308d512f5df277e5b9d82c6c88f47cb048390245dd8b34f598e03c41ad9286576add9f75dfdd1cbb2230101b60dc6bed844f85de9fab1247a76
data/README.md CHANGED
@@ -61,7 +61,7 @@ And how to do basic maths on itself:
61
61
 
62
62
  ```ruby
63
63
  (Duration.from_millis(42) + Duration.from_secs(1)).to_s # => "1.042s"
64
- (Duration.from_millis(42) - Duration.from_secs(-1)).to_s # => "-958ms"
64
+ (Duration.from_millis(42) - Duration.from_secs(1)).to_s # => "-958ms"
65
65
  ```
66
66
 
67
67
  `Instant` does some simple maths too:
@@ -2,8 +2,6 @@
2
2
 
3
3
  require 'monotime/version'
4
4
 
5
- require 'dry-equalizer'
6
-
7
5
  module Monotime
8
6
  # A measurement from the operating system's monotonic clock, with up to
9
7
  # nanosecond precision.
@@ -12,136 +10,202 @@ module Monotime
12
10
  # non-portable outside the process that created it.
13
11
  protected def ns() @ns end
14
12
 
15
- include Dry::Equalizer(:ns)
16
13
  include Comparable
17
14
 
18
- # Create a new +Instant+ from a given nanosecond measurement, defaulting to
19
- # that given by +Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond))+.
15
+ # Create a new +Instant+ from an optional nanosecond measurement.
20
16
  #
21
17
  # Users should generally *not* pass anything to this function.
18
+ #
19
+ # @param nanos [Integer]
22
20
  def initialize(nanos = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond))
23
21
  @ns = Integer(nanos)
24
22
  end
25
23
 
26
24
  # An alias to +new+, and generally preferred over it.
25
+ #
26
+ # @return [Instant]
27
27
  def self.now
28
28
  new
29
29
  end
30
30
 
31
31
  # Return a +Duration+ between this +Instant+ and another.
32
+ #
33
+ # @param earlier [Instant]
34
+ # @return [Duration]
32
35
  def duration_since(earlier)
33
- case earlier
34
- when Instant then earlier - self
35
- else raise TypeError, 'Not an Instant'
36
- end
36
+ raise TypeError, 'Not an Instant' unless earlier.is_a?(Instant)
37
+
38
+ earlier - self
37
39
  end
38
40
 
39
41
  # Return a +Duration+ since this +Instant+ and now.
42
+ #
43
+ # @return [Duration]
40
44
  def elapsed
41
45
  duration_since(self.class.now)
42
46
  end
43
47
 
44
48
  # Sugar for +elapsed.to_s+.
49
+ #
50
+ # @see Duration#to_s
45
51
  def to_s(*args)
46
52
  elapsed.to_s(*args)
47
53
  end
48
54
 
49
55
  # Add a +Duration+ to this +Instant+, returning a new +Instant+.
56
+ #
57
+ # @param other [Duration, #to_nanos]
58
+ # @return [Instant]
50
59
  def +(other)
51
- case other
52
- when Duration then Instant.new(@ns + other.to_nanos)
53
- else raise TypeError, 'Not a Duration'
54
- end
60
+ return TypeError, 'Not one of: [Duration, #to_nanos]' unless other.respond_to?(:to_nanos)
61
+
62
+ Instant.new(@ns + other.to_nanos)
55
63
  end
56
64
 
57
65
  # Subtract another +Instant+ to generate a +Duration+ between the two,
58
66
  # or a +Duration+, to generate an +Instant+ offset by it.
67
+ #
68
+ # @param other [Instant, Duration, #to_nanos]
69
+ # @return [Duration, Instant]
59
70
  def -(other)
60
- case other
61
- when Instant then Duration.new(@ns - other.ns)
62
- when Duration then Instant.new(@ns - other.to_nanos)
63
- else raise TypeError, 'Not an Instant or Duration'
71
+ if other.is_a?(Instant)
72
+ Duration.new(@ns - other.ns)
73
+ elsif other.respond_to?(:to_nanos)
74
+ Instant.new(@ns - other.to_nanos)
75
+ else
76
+ raise TypeError, 'Not one of: [Instant, Duration, #to_nanos]'
64
77
  end
65
78
  end
66
79
 
67
80
  # Compare this +Instant+ with another.
68
81
  def <=>(other)
69
- case other
70
- when Instant then @ns <=> other.ns
71
- else raise TypeError, 'Not an Instant'
72
- end
82
+ @ns <=> other.ns if other.is_a?(Instant)
83
+ end
84
+
85
+ def ==(other)
86
+ other.is_a?(Instant) && @ns == other.ns
87
+ end
88
+
89
+ alias eql? ==
90
+
91
+ def hash
92
+ self.class.hash ^ @ns.hash
73
93
  end
74
94
  end
75
95
 
76
96
  # A type representing a span of time in nanoseconds.
77
97
  class Duration
78
- include Dry::Equalizer(:to_nanos)
79
98
  include Comparable
80
99
 
81
100
  # Create a new +Duration+ of a specified number of nanoseconds, zero by
82
101
  # default.
102
+ #
103
+ # @param nanos [Integer]
83
104
  def initialize(nanos = 0)
84
105
  @ns = Integer(nanos)
85
106
  end
86
107
 
87
108
  class << self
88
109
  # Generate a new +Duration+ measuring the given number of seconds.
110
+ #
111
+ # @param secs [Numeric]
112
+ # @return [Duration]
89
113
  def from_secs(secs)
90
114
  new(Integer(Float(secs) * 1_000_000_000))
91
115
  end
92
116
 
93
117
  # Generate a new +Duration+ measuring the given number of milliseconds.
118
+ #
119
+ # @param millis [Numeric]
120
+ # @return [Duration]
94
121
  def from_millis(millis)
95
122
  new(Integer(Float(millis) * 1_000_000))
96
123
  end
97
124
 
98
125
  # Generate a new +Duration+ measuring the given number of microseconds.
126
+ #
127
+ # @param micros [Numeric]
128
+ # @return [Duration]
99
129
  def from_micros(micros)
100
130
  new(Integer(Float(micros) * 1_000))
101
131
  end
102
132
 
103
133
  # Generate a new +Duration+ measuring the given number of nanoseconds.
134
+ #
135
+ # @param nanos [Numeric]
136
+ # @return [Duration]
104
137
  def from_nanos(nanos)
105
138
  new(Integer(nanos))
106
139
  end
107
140
 
108
141
  # Return a +Duration+ measuring the elapsed time of the yielded block.
142
+ #
143
+ # @return [Duration]
109
144
  def measure
110
145
  Instant.now.tap { yield }.elapsed
111
146
  end
112
147
  end
113
148
 
114
149
  # Add another +Duration+ to this one, returning a new +Duration+.
150
+ #
151
+ # @param [Duration, #to_nanos]
152
+ #
153
+ # @return [Duration]
115
154
  def +(other)
155
+ raise TypeError, 'Not one of: [Duration, #to_nanos]' unless other.respond_to?(:to_nanos)
156
+
116
157
  Duration.new(to_nanos + other.to_nanos)
117
158
  end
118
159
 
119
160
  # Subtract another +Duration+ from this one, returning a new +Duration+.
161
+ #
162
+ # @param [Duration, #to_nanos]
163
+ # @return [Duration]
120
164
  def -(other)
165
+ raise TypeError, 'Not one of: [Duration, #to_nanos]' unless other.respond_to?(:to_nanos)
166
+
121
167
  Duration.new(to_nanos - other.to_nanos)
122
168
  end
123
169
 
124
170
  # Compare this +Duration+ with another.
125
171
  def <=>(other)
126
- to_nanos <=> other.to_nanos
172
+ to_nanos <=> other.to_nanos if other.is_a? Duration
173
+ end
174
+
175
+ def ==(other)
176
+ other.is_a?(Duration) && to_nanos == other.to_nanos
177
+ end
178
+
179
+ alias eql? ==
180
+
181
+ def hash
182
+ self.class.hash ^ to_nanos.hash
127
183
  end
128
184
 
129
185
  # Return this +Duration+ in seconds.
186
+ #
187
+ # @return [Float]
130
188
  def to_secs
131
189
  to_nanos / 1_000_000_000.0
132
190
  end
133
191
 
134
192
  # Return this +Duration+ in milliseconds.
193
+ #
194
+ # @return [Float]
135
195
  def to_millis
136
196
  to_nanos / 1_000_000.0
137
197
  end
138
198
 
139
199
  # Return this +Duration+ in microseconds.
200
+ #
201
+ # @return [Float]
140
202
  def to_micros
141
203
  to_nanos / 1_000.0
142
204
  end
143
205
 
144
206
  # Return this +Duration+ in nanoseconds.
207
+ #
208
+ # @return [Integer]
145
209
  def to_nanos
146
210
  @ns
147
211
  end
@@ -153,11 +217,16 @@ module Monotime
153
217
  [0, 'ns']
154
218
  ].map(&:freeze).freeze
155
219
 
220
+ private_constant :DIVISORS
221
+
156
222
  # Format this +Duration+ into a human-readable string, with a given number
157
223
  # of decimal places.
158
224
  #
159
225
  # The exact format is subject to change, users with specific requirements
160
226
  # are encouraged to use their own formatting methods.
227
+ #
228
+ # @param precision [Integer] the maximum number of decimal places
229
+ # @return [String]
161
230
  def to_s(precision = 9)
162
231
  precision = Integer(precision).abs
163
232
  ns = to_nanos.abs
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Monotime
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
@@ -31,8 +31,6 @@ Gem::Specification.new do |spec|
31
31
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
32
  spec.require_paths = ["lib"]
33
33
 
34
- spec.add_dependency "dry-equalizer", '~> 0'
35
-
36
34
  spec.add_development_dependency "bundler", "~> 1.16"
37
35
  spec.add_development_dependency "rake", "~> 10.0"
38
36
  spec.add_development_dependency "minitest", "~> 5.0"
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: monotime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Hurst
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-02 00:00:00.000000000 Z
11
+ date: 2018-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: dry-equalizer
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: bundler
29
15
  requirement: !ruby/object:Gem::Requirement