ruby-measurement 1.1.0 → 1.2.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.
- data/CHANGELOG.md +5 -0
- data/README.md +53 -33
- data/lib/ruby-measurement.rb +1 -0
- data/lib/ruby-measurement/core_ext.rb +3 -0
- data/lib/ruby-measurement/core_ext/numeric.rb +7 -0
- data/lib/ruby-measurement/core_ext/string.rb +11 -0
- data/lib/ruby-measurement/core_ext/symbol.rb +7 -0
- data/lib/ruby-measurement/measurement.rb +19 -58
- data/lib/ruby-measurement/version.rb +1 -1
- data/spec/ruby-measurement/core_ext/numeric_spec.rb +8 -0
- data/spec/ruby-measurement/core_ext/string_spec.rb +37 -0
- data/spec/ruby-measurement/core_ext/symbol_spec.rb +15 -0
- metadata +16 -6
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## ruby-measurement 1.2.0 (Mar 16, 2013)
|
2
|
+
|
3
|
+
* Implement `String#to_measurement`, `String#to_unit`,
|
4
|
+
`Symbol#to_unit`, and `Numeric#to_measurement`. *Matt Huggins*
|
5
|
+
|
1
6
|
## ruby-measurement 1.1.0 (Feb 6, 2013)
|
2
7
|
|
3
8
|
* Move unit definition logic into `Unit` class. *Matt Huggins*
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Measurement
|
2
2
|
|
3
3
|
[](http://travis-ci.org/mhuggins/ruby-measurement)
|
4
|
+
[](https://codeclimate.com/github/mhuggins/ruby-measurement)
|
4
5
|
|
5
6
|
[ruby-measurement](https://github.com/mhuggins/ruby-measurement) is a simple
|
6
7
|
Ruby gem for calculating and converting units of measure.
|
@@ -23,60 +24,79 @@ Or install it yourself as:
|
|
23
24
|
|
24
25
|
The `Measurement` class is responsible for parsing strings to determine the
|
25
26
|
quantity entered as well as the unit of measure. This can be done through the
|
26
|
-
`parse` method.
|
27
|
+
`parse` method, which returns a `Measurement` object.
|
27
28
|
|
28
|
-
Measurement.parse('3 feet')
|
29
|
-
Measurement.parse('25 fl oz')
|
30
|
-
Measurement.parse('12 tonnes')
|
31
|
-
Measurement.parse('25 "')
|
29
|
+
Measurement.parse('3 feet') # => 3.0 ft.
|
30
|
+
Measurement.parse('25 fl oz') # => 25.0 fl. oz.
|
31
|
+
Measurement.parse('12 tonnes') # => 12.0 t
|
32
|
+
Measurement.parse('25 "') # => 25.0 in.
|
32
33
|
|
33
|
-
|
34
|
+
A measurement includes both a quantity and a unit. Refer to the "Units"
|
35
|
+
section below for more details on how to interact with a unit.
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
measurement = Measurement.parse('12 yd') # => 12.0 yd.
|
38
|
+
measurement.quantity # => 12.0
|
39
|
+
measurement.unit # => yd.
|
38
40
|
|
39
|
-
The
|
41
|
+
The `String` and `Numeric` classes have also been extended to simplify the
|
42
|
+
parsing of measurement values.
|
40
43
|
|
41
|
-
|
42
|
-
|
43
|
-
u.aliases # => ["yd.", "yd", "yard", "yards"]
|
44
|
+
'12 yd'.to_measurement # => 12.0 yd.
|
45
|
+
20.to_measurement # => 20.0 count
|
44
46
|
|
45
|
-
|
47
|
+
### Units
|
48
|
+
|
49
|
+
The `Measurement::Unit` class is used to represent the units for a measurement.
|
50
|
+
Predefined units can be looked up via `Measurement::Unit[]`.
|
51
|
+
|
52
|
+
unit = Measurement::Unit[:dozen] # => doz
|
53
|
+
|
54
|
+
Similarly, the `String#to_unit` and `Symbol#to_unit` method can be used to
|
55
|
+
accomplish the same thing.
|
56
|
+
|
57
|
+
unit = 'dozen'.to_unit # => doz
|
58
|
+
unit = :dozen.to_unit # => doz
|
59
|
+
|
60
|
+
Units provide access to their names and aliases.
|
61
|
+
|
62
|
+
unit.name # => "yd."
|
63
|
+
unit.aliases # => ["yd.", "yd", "yard", "yards"]
|
64
|
+
|
65
|
+
### Converting units
|
46
66
|
|
47
67
|
This gem allows you to convert among compatible units as long as a conversion
|
48
68
|
has been supplied when defining a unit. The default supplied units include
|
49
69
|
conversions among the same unit types (e.g.: converting feet to yards or meters
|
50
70
|
to kilometers).
|
51
71
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
72
|
+
measurement = Measurement.parse('3 feet') # => 3.0 ft.
|
73
|
+
measurement.convert_to(:yards) # => 1.0 yd.
|
74
|
+
measurement.convert_to(:in) # => 36.0 in.
|
75
|
+
measurement.convert_to(:inches) # => 36.0 in.
|
56
76
|
|
57
77
|
NOTE: Converting between metric and U.S. customary systems is currently not
|
58
78
|
included by default. It is intended to be shipped in a future release.
|
59
79
|
|
60
|
-
|
80
|
+
### Calculations
|
61
81
|
|
62
82
|
This gem allows you to add, subtract, multiply, or divide measurements that can
|
63
83
|
be converted into one-another.
|
64
84
|
|
65
|
-
|
66
|
-
|
67
|
-
|
85
|
+
measurement1 = Measurement.parse('3 feet') # => 3.0 ft.
|
86
|
+
measurement2 = Measurement.parse('6 inch') # => 6.0 in.
|
87
|
+
measurement1 + measurement2 # => 3.5 ft.
|
68
88
|
|
69
89
|
Additionally, measurements can have basic math operations performed using basic
|
70
90
|
numeric values.
|
71
91
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
92
|
+
measurement = Measurement.parse('2 yards') # => 2.0 yd.
|
93
|
+
measurement * 6 # => 12.0 yd.
|
94
|
+
measurement / 5 # => 0.4 yd.
|
95
|
+
measurement + 3 # => 5.0 yd.
|
96
|
+
measurement - 1 # => 1.0 yd.
|
97
|
+
measurement ** 2 # => 4.0 yd.
|
78
98
|
|
79
|
-
|
99
|
+
### Specifying units
|
80
100
|
|
81
101
|
By default, ruby-measurement ships with common areas, lengths, volumes, and
|
82
102
|
weights/masses for the metric and U.S. customary systems. This happens
|
@@ -112,7 +132,7 @@ system.
|
|
112
132
|
require 'ruby-measurement/definitions/us_customary/volume'
|
113
133
|
require 'ruby-measurement/definitions/us_customary/weight'
|
114
134
|
|
115
|
-
|
135
|
+
### Defining custom units & conversions
|
116
136
|
|
117
137
|
This gem also enabled you to define units of measure that aren't included by
|
118
138
|
default.
|
@@ -138,9 +158,9 @@ default.
|
|
138
158
|
Note that the first value passed to `Measurement.define` is the unit format
|
139
159
|
that will be used when displaying a measurement.
|
140
160
|
|
141
|
-
Measurement.parse('3 yr')
|
142
|
-
Measurement.parse('3 year')
|
143
|
-
Measurement.parse('3 years')
|
161
|
+
Measurement.parse('3 yr') # => 3.0 yr
|
162
|
+
Measurement.parse('3 year') # => 3.0 yr
|
163
|
+
Measurement.parse('3 years') # => 3.0 yr
|
144
164
|
|
145
165
|
## Contributing
|
146
166
|
|
data/lib/ruby-measurement.rb
CHANGED
@@ -29,64 +29,23 @@ class Measurement
|
|
29
29
|
"#{quantity} #{unit}"
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
self.class
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
def -(obj)
|
48
|
-
case obj
|
49
|
-
when Numeric
|
50
|
-
self.class.new(quantity - obj.to_f, unit)
|
51
|
-
when self.class
|
52
|
-
if obj.unit == unit
|
53
|
-
self.class.new(quantity - obj.quantity, unit)
|
54
|
-
else
|
55
|
-
self - obj.convert_to(unit)
|
32
|
+
%w(+ - * /).each do |operator|
|
33
|
+
class_eval <<-END, __FILE__, __LINE__ + 1
|
34
|
+
def #{operator}(obj)
|
35
|
+
case obj
|
36
|
+
when Numeric
|
37
|
+
self.class.new(quantity #{operator} obj.to_f, unit)
|
38
|
+
when self.class
|
39
|
+
if obj.unit == unit
|
40
|
+
self.class.new(quantity #{operator} obj.quantity, unit)
|
41
|
+
else
|
42
|
+
self #{operator} obj.convert_to(unit)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
raise ArgumentError, "Invalid arithmetic: \#{self} #{operator} \#{obj}"
|
46
|
+
end
|
56
47
|
end
|
57
|
-
|
58
|
-
raise ArgumentError, "Invalid arithmetic: #{self} - #{obj}"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def *(obj)
|
63
|
-
case obj
|
64
|
-
when Numeric
|
65
|
-
self.class.new(quantity * obj.to_f, unit)
|
66
|
-
when self.class
|
67
|
-
if obj.unit == unit
|
68
|
-
self.class.new(quantity * obj.quantity, unit)
|
69
|
-
else
|
70
|
-
self * obj.convert_to(unit)
|
71
|
-
end
|
72
|
-
else
|
73
|
-
raise ArgumentError, "Invalid arithmetic: #{self} * #{obj}"
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def /(obj)
|
78
|
-
case obj
|
79
|
-
when Numeric
|
80
|
-
self.class.new(quantity / obj.to_f, unit)
|
81
|
-
when self.class
|
82
|
-
if obj.unit == unit
|
83
|
-
self.class.new(quantity / obj.quantity, unit)
|
84
|
-
else
|
85
|
-
self / obj.convert_to(unit)
|
86
|
-
end
|
87
|
-
else
|
88
|
-
raise ArgumentError, "Invalid arithmetic: #{self} / #{obj}"
|
89
|
-
end
|
48
|
+
END
|
90
49
|
end
|
91
50
|
|
92
51
|
def **(obj)
|
@@ -131,7 +90,7 @@ class Measurement
|
|
131
90
|
quantity = whole.to_f
|
132
91
|
elsif str =~ RATIONAL_REGEX
|
133
92
|
whole, _, numerator, denominator, unit_name = str.scan(RATIONAL_REGEX).first
|
134
|
-
|
93
|
+
|
135
94
|
if numerator && denominator
|
136
95
|
numerator = numerator.to_f + (denominator.to_f * whole.to_f)
|
137
96
|
denominator = denominator.to_f
|
@@ -154,6 +113,8 @@ class Measurement
|
|
154
113
|
Unit.define(unit_name, &block)
|
155
114
|
end
|
156
115
|
|
116
|
+
private
|
117
|
+
|
157
118
|
define(:count) do |unit|
|
158
119
|
unit.convert_to(:dozen) { |value| value / 12.0 }
|
159
120
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
describe '#to_measurement' do
|
5
|
+
describe 'with valid quantity' do
|
6
|
+
subject { '3' }
|
7
|
+
specify { subject.to_measurement.should eq Measurement.new(3) }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'with valid quantity and unit' do
|
11
|
+
subject { '3 dozen' }
|
12
|
+
specify { subject.to_measurement.should eq Measurement.new(3, :dozen) }
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'with valid quantity and invalid unit' do
|
16
|
+
subject { '3 people' }
|
17
|
+
specify { expect { subject.to_measurement }.to raise_error }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'with invalid input' do
|
21
|
+
subject { 'foobar' }
|
22
|
+
specify { expect { subject.to_measurement }.to raise_error }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#to_unit' do
|
27
|
+
describe 'with valid unit' do
|
28
|
+
subject { 'dozen' }
|
29
|
+
specify { subject.to_unit.should eq Measurement::Unit[:dozen] }
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'with invalid unit' do
|
33
|
+
subject { 'person' }
|
34
|
+
specify { expect { subject.to_unit }.to raise_error }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Symbol do
|
4
|
+
describe '#to_unit' do
|
5
|
+
describe 'with valid unit' do
|
6
|
+
subject { :dozen }
|
7
|
+
specify { subject.to_unit.should eq Measurement::Unit[:dozen] }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'with invalid unit' do
|
11
|
+
subject { :person }
|
12
|
+
specify { expect { subject.to_unit }.to raise_error }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-measurement
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &2160834380 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2160834380
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &2160833960 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2160833960
|
36
36
|
description: Simple gem for calculating and converting measurements
|
37
37
|
email: matt.huggins@gmail.com
|
38
38
|
executables: []
|
@@ -47,6 +47,10 @@ files:
|
|
47
47
|
- README.md
|
48
48
|
- Rakefile
|
49
49
|
- lib/ruby-measurement.rb
|
50
|
+
- lib/ruby-measurement/core_ext.rb
|
51
|
+
- lib/ruby-measurement/core_ext/numeric.rb
|
52
|
+
- lib/ruby-measurement/core_ext/string.rb
|
53
|
+
- lib/ruby-measurement/core_ext/symbol.rb
|
50
54
|
- lib/ruby-measurement/definitions.rb
|
51
55
|
- lib/ruby-measurement/definitions/metric.rb
|
52
56
|
- lib/ruby-measurement/definitions/metric/area.rb
|
@@ -64,6 +68,9 @@ files:
|
|
64
68
|
- lib/ruby-measurement/unit.rb
|
65
69
|
- lib/ruby-measurement/version.rb
|
66
70
|
- ruby-measurement.gemspec
|
71
|
+
- spec/ruby-measurement/core_ext/numeric_spec.rb
|
72
|
+
- spec/ruby-measurement/core_ext/string_spec.rb
|
73
|
+
- spec/ruby-measurement/core_ext/symbol_spec.rb
|
67
74
|
- spec/ruby-measurement/definitions/metric/area_spec.rb
|
68
75
|
- spec/ruby-measurement/definitions/metric/capacity_spec.rb
|
69
76
|
- spec/ruby-measurement/definitions/metric/length_spec.rb
|
@@ -105,6 +112,9 @@ signing_key:
|
|
105
112
|
specification_version: 3
|
106
113
|
summary: Simple gem for calculating and converting measurements
|
107
114
|
test_files:
|
115
|
+
- spec/ruby-measurement/core_ext/numeric_spec.rb
|
116
|
+
- spec/ruby-measurement/core_ext/string_spec.rb
|
117
|
+
- spec/ruby-measurement/core_ext/symbol_spec.rb
|
108
118
|
- spec/ruby-measurement/definitions/metric/area_spec.rb
|
109
119
|
- spec/ruby-measurement/definitions/metric/capacity_spec.rb
|
110
120
|
- spec/ruby-measurement/definitions/metric/length_spec.rb
|