duration.rb 0.6.2 → 0.7.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 +4 -4
- data/CHANGELOG +10 -0
- data/README.md +44 -11
- data/lib/Duration/Common.rb +25 -0
- data/lib/Duration/VERSION.rb +1 -1
- data/test/Duration/Common_test.rb +54 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c8e29deede3e2da3e3291bda645d370df91c119d6b6263c33dfe4c902f927583
|
|
4
|
+
data.tar.gz: 0166b41b22ce52109bdf30a99a141bd766e18094dbaa0ec7ae55b39a8ead08fa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5587052c84be1c21d2616745be9eb1cdf009dc5877db0b0e2e66ec8eb4983867c67b6a1449e10e27d5ccac61dd5a06629034611171a412edc458ab45ad3da6f1
|
|
7
|
+
data.tar.gz: 20a868eb602e70efa4dada46349ccbafca1c53e9c9bdc9021a797fb37b286da729c3d4f1a67472a451b06a13b1219bdf3981809e17d15e9f5c7b996f9f27d8a8
|
data/CHANGELOG
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 20260822
|
|
4
|
+
|
|
5
|
+
0.7.0: + Duration::Common#to_s, #inspect.
|
|
6
|
+
|
|
7
|
+
1. + Duration::Common#to_s: the quantity and the unit, as "45 days". The unit is the class, so naming it says which duration this is without repeating the class. A quantity of one drops the plural.
|
|
8
|
+
2. + Duration::Common#inspect: the class and the quantity as it is held, as "Duration::Days(45)", after measurand's. Collections call inspect upon their elements, which is where the default ivar-and-address form was most often met. It is the one place an Integer 45 and a Rational 45/1 can be told apart, #to_s rendering both as "45 days".
|
|
9
|
+
3. ~ README.md: the eleven `# =>` comments which render a duration, being what irb prints and so #inspect, brought to the form it now returns. They had shown an approximation of the default, `#<Nanoseconds @nanoseconds=500>`, which was never quite what was printed either; + a Rendering section for #to_s and #inspect.
|
|
10
|
+
4. ~ Duration::VERSION: /0.6.2/0.7.0/
|
|
11
|
+
|
|
12
|
+
|
|
3
13
|
## 20260819
|
|
4
14
|
|
|
5
15
|
0.6.2: ~ duration.rb.gemspec: spec.files reordered, the globs first.
|
data/README.md
CHANGED
|
@@ -64,15 +64,15 @@ minutes reads the files for seconds and minutes and leaves the rest unread.
|
|
|
64
64
|
### Basic Duration Creation
|
|
65
65
|
```ruby
|
|
66
66
|
# Create durations using convenience methods
|
|
67
|
-
500.nanoseconds # =>
|
|
68
|
-
500.microseconds # =>
|
|
69
|
-
200.milliseconds # =>
|
|
70
|
-
1.second # =>
|
|
71
|
-
30.minutes # =>
|
|
72
|
-
2.hours # =>
|
|
73
|
-
7.days # =>
|
|
74
|
-
4.weeks # =>
|
|
75
|
-
6.months # =>
|
|
67
|
+
500.nanoseconds # => Duration::Nanoseconds(500)
|
|
68
|
+
500.microseconds # => Duration::Microseconds(500)
|
|
69
|
+
200.milliseconds # => Duration::Milliseconds(200)
|
|
70
|
+
1.second # => Duration::Seconds(1)
|
|
71
|
+
30.minutes # => Duration::Minutes(30)
|
|
72
|
+
2.hours # => Duration::Hours(2)
|
|
73
|
+
7.days # => Duration::Days(7)
|
|
74
|
+
4.weeks # => Duration::Weeks(4)
|
|
75
|
+
6.months # => Duration::Months(6)
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
### Conversions
|
|
@@ -83,13 +83,46 @@ minutes reads the files for seconds and minutes and leaves the rest unread.
|
|
|
83
83
|
|
|
84
84
|
# Convert between units. The result is exact (a Rational internally) when the
|
|
85
85
|
# input is exact; call to_f at the edge for a float.
|
|
86
|
-
90.minutes.to_hours # =>
|
|
86
|
+
90.minutes.to_hours # => Duration::Hours((3/2))
|
|
87
87
|
90.minutes.to_hours.to_f # => 1.5
|
|
88
88
|
1.5.hours.to_minutes.to_i # => 90
|
|
89
89
|
1.day.to_seconds.to_i # => 86400
|
|
90
90
|
5.minutes.to_hours.to_f # => 0.08333333333333333
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
+
### Rendering
|
|
94
|
+
|
|
95
|
+
`to_s` names the quantity and the unit — the unit being the class, naming it says
|
|
96
|
+
which duration this is without repeating it.
|
|
97
|
+
|
|
98
|
+
```ruby
|
|
99
|
+
45.days.to_s # => "45 days"
|
|
100
|
+
1.day.to_s # => "1 day"
|
|
101
|
+
1.5.hours.to_s # => "1.5 hours"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The quantity prints as it is held. A Rational which came out whole prints as a whole
|
|
105
|
+
number, and one which did not stays a ratio rather than being expanded into a decimal
|
|
106
|
+
it is not:
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
45.days.to_weeks.to_s # => "45/7 weeks"
|
|
110
|
+
90.minutes.to_hours.to_s # => "3/2 hours"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Call `to_f` where a decimal is wanted, as elsewhere — the rounding happens upon
|
|
114
|
+
request and not before.
|
|
115
|
+
|
|
116
|
+
`inspect` is the other form: the class and the quantity as it is actually held. It is
|
|
117
|
+
the one place an `Integer` 45 and a `Rational` 45/1 can be told apart, `to_s` rendering
|
|
118
|
+
both as `"45 days"`.
|
|
119
|
+
|
|
120
|
+
```ruby
|
|
121
|
+
45.days.inspect # => "Duration::Days(45)"
|
|
122
|
+
45.days.to_weeks.inspect # => "Duration::Weeks((45/7))"
|
|
123
|
+
{held_for: 45.days}.inspect # => "{held_for: Duration::Days(45)}"
|
|
124
|
+
```
|
|
125
|
+
|
|
93
126
|
### Arithmetic and Comparison
|
|
94
127
|
```ruby
|
|
95
128
|
# Durations add and subtract, with the left operand's unit deciding the result:
|
|
@@ -101,7 +134,7 @@ minutes reads the files for seconds and minutes and leaves the rest unread.
|
|
|
101
134
|
5.minutes == 300.seconds # => true
|
|
102
135
|
90.seconds > 1.minute # => true
|
|
103
136
|
[1.hour, 30.seconds, 5.minutes].sort
|
|
104
|
-
# => [30
|
|
137
|
+
# => [Duration::Seconds(30), Duration::Minutes(5), Duration::Hours(1)]
|
|
105
138
|
|
|
106
139
|
# Scaled by a number, a duration stays a duration and keeps its unit:
|
|
107
140
|
5.minutes * 3 # => #<Minutes @minutes=15>
|
data/lib/Duration/Common.rb
CHANGED
|
@@ -36,6 +36,24 @@ module Duration
|
|
|
36
36
|
quantity <=> other.send(:"to_#{unit}").quantity
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
# The unit is the class, so naming it says which duration this is without
|
|
40
|
+
# repeating the class: 45 days rather than #<Duration::Days:0x000... The
|
|
41
|
+
# quantity is rendered as it is held, an exact Rational staying exact, this
|
|
42
|
+
# library manufacturing no precision it was not given and discarding none
|
|
43
|
+
# it was.
|
|
44
|
+
def to_s
|
|
45
|
+
"#{rendered_quantity} #{quantity == 1 ? unit.to_s.chomp('s') : unit}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# The class and the quantity as it is actually held, after measurand: to_s
|
|
49
|
+
# is what a reader wants and inspect is what the object is. It is the one
|
|
50
|
+
# place the difference between an Integer 45 and a Rational 45/1 shows,
|
|
51
|
+
# which in a library this careful about exactness is worth being able to
|
|
52
|
+
# see.
|
|
53
|
+
def inspect
|
|
54
|
+
"#{self.class}(#{quantity.inspect})"
|
|
55
|
+
end
|
|
56
|
+
|
|
39
57
|
protected
|
|
40
58
|
|
|
41
59
|
def quantity
|
|
@@ -44,6 +62,13 @@ module Duration
|
|
|
44
62
|
|
|
45
63
|
private
|
|
46
64
|
|
|
65
|
+
# A Rational which came out whole prints as its numerator, since 45/1 days
|
|
66
|
+
# says nothing 45 days does not. A Rational which did not stays a ratio:
|
|
67
|
+
# 45/7 weeks is what 45 days is, and 6.428571428571429 is not.
|
|
68
|
+
def rendered_quantity
|
|
69
|
+
quantity.is_a?(Rational) && quantity.denominator == 1 ? quantity.numerator.to_s : quantity.to_s
|
|
70
|
+
end
|
|
71
|
+
|
|
47
72
|
def combine(operator, other)
|
|
48
73
|
unless other.is_a?(Duration::Common)
|
|
49
74
|
raise TypeError, "can't combine #{self.class} with #{other.class}"
|
data/lib/Duration/VERSION.rb
CHANGED
|
@@ -98,4 +98,58 @@ describe Duration::Common do
|
|
|
98
98
|
_((1.hour - 50.minutes).to_minutes.to_f).must_equal 10.0
|
|
99
99
|
end
|
|
100
100
|
end
|
|
101
|
+
|
|
102
|
+
describe "#to_s" do
|
|
103
|
+
it "names the quantity and the unit" do
|
|
104
|
+
_(45.days.to_s).must_equal '45 days'
|
|
105
|
+
_(500.nanoseconds.to_s).must_equal '500 nanoseconds'
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "drops the plural at one" do
|
|
109
|
+
_(1.day.to_s).must_equal '1 day'
|
|
110
|
+
_(1.month.to_s).must_equal '1 month'
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "keeps a float a float" do
|
|
114
|
+
_(1.5.hours.to_s).must_equal '1.5 hours'
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "prints a whole Rational as a whole number" do
|
|
118
|
+
_(Duration::Days.new(45r).to_s).must_equal '45 days'
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "keeps an exact ratio a ratio rather than expanding it" do
|
|
122
|
+
# 45 days is exactly 45/7 weeks, and 6.428571428571429 is not.
|
|
123
|
+
_(45.days.to_weeks.to_s).must_equal '45/7 weeks'
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "reads the unit from the class rather than repeating it" do
|
|
127
|
+
_(90.minutes.to_hours.to_s).must_equal '3/2 hours'
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe "#inspect" do
|
|
132
|
+
it "names the class and the quantity as held" do
|
|
133
|
+
_(45.days.inspect).must_equal 'Duration::Days(45)'
|
|
134
|
+
_(1.5.hours.inspect).must_equal 'Duration::Hours(1.5)'
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "carries no address or ivar dump" do
|
|
138
|
+
_(45.days.inspect).wont_match(/0x|@days/)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "shows an exact quantity as the Rational it is, where to_s does not" do
|
|
142
|
+
_(45.days.to_weeks.to_s).must_equal '45/7 weeks'
|
|
143
|
+
_(45.days.to_weeks.inspect).must_equal 'Duration::Weeks((45/7))'
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "distinguishes a whole Rational from an Integer, where to_s cannot" do
|
|
147
|
+
_(Duration::Days.new(45r).to_s).must_equal 45.days.to_s
|
|
148
|
+
_(Duration::Days.new(45r).inspect).wont_equal 45.days.inspect
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "reaches a duration held inside a collection" do
|
|
152
|
+
_({held_for: 45.days}.inspect).must_equal '{held_for: Duration::Days(45)}'
|
|
153
|
+
end
|
|
154
|
+
end
|
|
101
155
|
end
|