quantify 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +151 -99
- data/lib/quantify/dimensions.rb +6 -6
- data/lib/quantify/exception.rb +14 -12
- data/lib/quantify/quantity.rb +17 -10
- data/lib/quantify/unit/base_unit.rb +6 -6
- data/lib/quantify/unit/compound_base_unit.rb +2 -2
- data/lib/quantify/unit/compound_unit.rb +6 -6
- data/lib/quantify/unit/prefix/base_prefix.rb +0 -2
- data/lib/quantify/unit/prefix/prefix.rb +1 -1
- data/lib/quantify/unit/unit.rb +4 -4
- data/spec/quantity_spec.rb +15 -0
- metadata +3 -3
data/README
CHANGED
@@ -1,115 +1,167 @@
|
|
1
|
-
A gem to support
|
1
|
+
A gem to support physical quantities and unit conversions
|
2
2
|
Licensed under the MIT license (See COPYING file for details)
|
3
3
|
Author: Andrew Berkeley (andrew.berkeley.is@googlemail.com)
|
4
4
|
Homepage: https://github.com/spatchcock/quantify
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
unit = Unit.km #=> #<Quantify::Unit::SI:0xb75c9718 ... >
|
9
|
-
unit.name #=> 'kilometre'
|
10
|
-
unit.symbol #=> 'kg'
|
11
|
-
unit.dimensions #=> #<Quantify::Dimensions:0xb75c4254 .. >
|
12
|
-
unit.measures #=> 'length'
|
13
|
-
unit.alternatives :name #=> ['metre', 'megametre', 'gigametre', 'terametre', 'angstrom',
|
14
|
-
# 'astronomical unit', 'baromil', 'chain', 'dram', 'ell', 'fathom',
|
15
|
-
# 'fermi', 'foot us survey', 'foot', 'furlong', 'hand', 'inch',
|
16
|
-
# 'nautical league', 'statute league', 'light year', 'line',
|
17
|
-
# 'link', 'yard']
|
18
|
-
other_unit = Unit.hour
|
19
|
-
other_unit.name #=> 'hour'
|
20
|
-
other_unit.symbol #=> 'h'
|
21
|
-
other_unit.measures #=> 'time'
|
22
|
-
other_unit.alternatives :symbol #=> [ 's', 'ks', 'Ms', 'Gs', 'Ts', 'd', 'min' ]
|
23
|
-
|
24
|
-
another_unit = unit / other_unit #=> #<Quantify::Unit::Compound:0xb74af323 ... >
|
25
|
-
another_unit.name #=> 'kilometer per hour'
|
26
|
-
another_unit.symbol #=> 'km h^-1'
|
27
|
-
another_unit.measures #=> 'velocity'
|
28
|
-
|
29
|
-
last_unit = Unit.m
|
30
|
-
last.unit.measures #=> 'length'
|
31
|
-
square = last_unit ** 2 #=> #<Quantify::Unit::Compound:0xb446f12f ... >
|
32
|
-
square.symbol #=> 'm^2'
|
33
|
-
square.measures #=> 'area'
|
34
|
-
|
35
|
-
Define quantity - method 1
|
36
|
-
|
37
|
-
quantity = Quantity.new(1234.5678, :lb) #=> #<Quantify::Quantity:0xjk39d570 ... >
|
38
|
-
quantity.value #=> 1234.5678
|
39
|
-
quantity.unit #=> #<Quantify::Unit::NonSI:0xb182124 ... >
|
40
|
-
quantity.unit.symbol #=> 'lb'
|
41
|
-
|
42
|
-
Define quantity - method 2
|
43
|
-
|
44
|
-
string = quantity.to_s #=> "1234.5678 lb"
|
45
|
-
quantity = Quantity.parse(string) #=> #<Quantify::Quantity:0xj982b4f9 ... >
|
46
|
-
quantity.to_s #=> "1234.5678 lb"
|
47
|
-
|
48
|
-
Define quantity - method 3
|
49
|
-
|
50
|
-
quantity = 1234.5678.lb #=> #<Quantify::Quantity:02387f7340 ... >
|
51
|
-
quantity.to_s #=> "1234.5678 lb"
|
52
|
-
|
53
|
-
Multiply by scalar
|
6
|
+
There are several ways to initialize a quantity object
|
54
7
|
|
55
|
-
|
56
|
-
|
8
|
+
mass = Quantity.new(100,:lb) => <Quantify::Quantity:0xb7332bbc ... >
|
9
|
+
mass = Quantity.new(100,'pound') => <Quantify::Quantity:0xb7332bbc ... >
|
10
|
+
mass = 100.lb => <Quantify::Quantity:0xb7332bbc ... >
|
11
|
+
mass = 100.pound => <Quantify::Quantity:0xb7332bbc ... >
|
12
|
+
mass = Quantity.parse "100 lb" => <Quantify::Quantity:0xb7332bbc ... >
|
13
|
+
mass = "100 lb".to_q => <Quantify::Quantity:0xb7332bbc ... >
|
57
14
|
|
58
|
-
|
15
|
+
Quantity object attributes
|
59
16
|
|
60
|
-
|
61
|
-
|
17
|
+
mass.value => 100.0
|
18
|
+
mass.unit => <Quantify::Unit::NonSI:0xb7332b08 ... >
|
19
|
+
mass.unit.name => "pound"
|
20
|
+
mass.unit.symbol => "lb"
|
62
21
|
|
63
|
-
|
64
|
-
|
22
|
+
# unique identifier, follows JScience
|
23
|
+
mass.unit.label => "lb"
|
24
|
+
mass.unit.pluralized_name => "pounds"
|
25
|
+
mass.to_s => "100 lb"
|
26
|
+
mass.to_s(:name) => "100 pounds"
|
65
27
|
|
66
|
-
|
28
|
+
# Describe the physical quantity represented by the quantity
|
29
|
+
mass.represents => "mass"
|
67
30
|
|
68
|
-
|
31
|
+
Convert a quantity to a different unit
|
69
32
|
|
70
|
-
|
33
|
+
energy = 100.kWh => <Quantify::Quantity:0xb7332bbc ... >
|
34
|
+
energy.to_s(:name) => "100 kilowatt hours"
|
71
35
|
|
72
|
-
|
73
|
-
|
74
|
-
kW.measures #=> 'power'
|
36
|
+
energy = quantity.to_megajoules => <Quantify::Quantity:0xb7332bbc ... >
|
37
|
+
energy.to_s => "360.0 MJ"
|
75
38
|
|
76
|
-
|
77
|
-
|
78
|
-
|
39
|
+
energy = quantity.to_MJ => <Quantify::Quantity:0xb7332bbc ... >
|
40
|
+
energy.to_s => "360.0 MJ"
|
41
|
+
|
42
|
+
energy = quantity.to(:MJ) => <Quantify::Quantity:0xb7332bbc ... >
|
43
|
+
energy.to_s => "360.0 MJ"
|
44
|
+
|
45
|
+
# Initialize a unit object and pass as conversion argument
|
46
|
+
unit = Unit.MJ => <Quantify::Unit::SI:0xb75c9718 ... >
|
47
|
+
energy = quantity.to(unit) => <Quantify::Quantity:0xb7332bbc ... >
|
48
|
+
energy.to_s => "360.0 MJ"
|
49
|
+
|
50
|
+
# Single line conversion of litres to barrels, returning only the value
|
51
|
+
5000.L.to_bbl.value => 31.4490528488754
|
52
|
+
|
53
|
+
Convert the units of a quantity with a compound unit
|
54
|
+
|
55
|
+
speed = 70.mi/1.h => <Quantify::Quantity:0xb7332bbc ... >
|
56
|
+
speed.to_s => "70.0 mi h^-1"
|
57
|
+
|
58
|
+
speed_in_kms = speed.to_km => <Quantify::Quantity:0xb7332bbc ... >
|
59
|
+
speed_in_kms.to_s => "112.65408 km h^-1"
|
60
|
+
|
61
|
+
speed_in_mins = speed_in_kms.to_min => <Quantify::Quantity:0xb7332bbc ... >
|
62
|
+
speed_in_mins.to_s => "1.877568 km min^-1"
|
63
|
+
|
64
|
+
Convert a quantity to the corresponding SI unit
|
65
|
+
|
66
|
+
energy = 100.kWh => <Quantify::Quantity:0xb7332bbc ... >
|
67
|
+
energy.to_s => "100 kWh"
|
68
|
+
si = quantity.to_si => <Quantify::Quantity:0x4j4j9sbc ... >
|
69
|
+
si.to_s => "360000000.0 J"
|
70
|
+
|
71
|
+
Operate on a quantity
|
72
|
+
|
73
|
+
mass = 10.kg * 3 => <Quantify::Quantity:0xb7332bbc ... >
|
74
|
+
mass.to_s => 30.0 kg
|
75
|
+
|
76
|
+
distance = 100.light_years / 20 => <Quantify::Quantity:0xb7332bbc ... >
|
77
|
+
distance.to_s => 5.0 ly
|
78
|
+
|
79
|
+
area = 10.m * 10.m => <Quantify::Quantity:0xb7332bbc ... >
|
80
|
+
area.to_s :name => 100.0 square metres
|
81
|
+
|
82
|
+
speed = 250.mi / 3.h => <Quantify::Quantity:0xb7332bbc ... >
|
83
|
+
speed.to_s(:name) => 83.3333333333333 miles per hour
|
84
|
+
|
85
|
+
speed = 70.mi/1.h => <Quantify::Quantity:0xb7332bbc ... >
|
86
|
+
time = 0.5.h => <Quantify::Quantity:3xf3472hjc ... >
|
87
|
+
distance = speed * time => <Quantify::Quantity:7d7f8g9d5g ... >
|
88
|
+
distance.to_s => 35.0 mi
|
89
|
+
|
90
|
+
Additional operations
|
91
|
+
The result of quantity operations is commonly a new quantity with a compound unit.
|
92
|
+
Unless the result is equivalent to one of the base SI units (m, kg, s, K, etc.) or
|
93
|
+
one of the following, square metre, cubic metre, joule, watt, newton or pascal, then
|
94
|
+
the compound unit represents appropriate combination of the units involved, albeit
|
95
|
+
with any like-units within the numerator and denominator grouped under a single
|
96
|
+
power/index.
|
97
|
+
|
98
|
+
Units are not automatically cancelled or rationalized (made consistent). This is
|
99
|
+
because it cannot be assumed that that is the desire of the user. For example, a
|
100
|
+
quantity with units <mass> per <mass> is technically dimensionless, but the user
|
101
|
+
might prefer to explicitly represent the units rather than reduce to a dimensionless
|
102
|
+
quantity. In addition, this quantity might be expressed in terms of grams per tonne,
|
103
|
+
and the user may not necessarily prefer a conversion into consistent mass units
|
104
|
+
(e.g. g/g or t/t). Therefore, the following methods are available...
|
105
|
+
|
106
|
+
# Where units representing the same physical quantity appear together, they can
|
107
|
+
# made consistent by simply converting to the unit which is desired
|
108
|
+
area = 12.yd * 36.ft => <Quantify::Quantity:0xb7332bbc ... >
|
109
|
+
area.to_s => "432.0 yd ft"
|
110
|
+
area.to_yd
|
111
|
+
area.to_s => "144.0 yd^2"
|
112
|
+
|
113
|
+
# Alternatively, all units within the numerator and denominator respectively
|
114
|
+
# can be standardized.
|
115
|
+
quantity = (12.ft*8.mi)/(1.s*8.min)
|
116
|
+
quantity.to_s => 12.0 ft mi s^-1 min^-1
|
117
|
+
quantity.rationalize_units!
|
118
|
+
quantity.to_s => 1056.0 ft^2 s^-2
|
119
|
+
|
120
|
+
# A quantity with arbitrary cancelable units can be cancelled manually
|
121
|
+
quantity = (12.m**6) / 2.m**2
|
122
|
+
quantity.to_s => "746496.0 m^6 m^-2"
|
123
|
+
quantity.cancel_base_units! :m
|
124
|
+
quantity.to_s => "746496.0 m^4"
|
125
|
+
|
126
|
+
Note: there are more comprehensive and flexible methods for manupulating compound
|
127
|
+
units available as part of of the class Unit::Compound. These can be used to
|
128
|
+
convert a conpound unit into the precise form required. If such an approach is
|
129
|
+
used, any quantity object can be converted to the new form by simply passing the
|
130
|
+
new unit object into the Quantity#to method.
|
131
|
+
|
132
|
+
Initialize a unit object
|
133
|
+
|
134
|
+
unit = Unit.for :km => <Quantify::Unit::SI:0xb75c9718 ... >
|
135
|
+
unit = Unit.km => <Quantify::Unit::SI:0xb75c9718 ... >
|
136
|
+
unit = Unit.kilometre => <Quantify::Unit::SI:0xb75c9718 ... >
|
137
|
+
|
138
|
+
unit.name => 'kilometre'
|
139
|
+
unit.symbol => 'kg'
|
140
|
+
unit.label => 'kg'
|
141
|
+
unit.dimensions => <Quantify::Dimensions:0xb75c4254 .. >
|
142
|
+
unit.measures => 'length'
|
143
|
+
unit.alternatives :name => ['metre','megametre','gigametre',
|
144
|
+
'terametre','angstrom','astronomical unit',
|
145
|
+
'baromil','chain','dram','ell','fathom',
|
146
|
+
'fermi','foot us survey','foot','furlong',
|
147
|
+
'hand','inch','nautical league',
|
148
|
+
'statute league','light year', 'line','link',
|
149
|
+
'yard']
|
79
150
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
kWh.alternatives :symbol #=> ['J', 'kJ', 'MJ', 'GJ', 'TJ', 'BTU', 'cal', 'CHU',
|
86
|
-
# 'dyn cm', 'eV', 'erg', 'Eh']
|
87
|
-
kWh.alternatives :name #=> ['joule', 'kilojoule', 'megajoule', 'gigajoule',
|
88
|
-
# 'terajoule', 'british thermal unit', 'calorie',
|
89
|
-
# 'celsius heat unit', 'dyne centimetre', 'electron volt',
|
90
|
-
# 'erg', 'hartree']
|
91
|
-
|
92
|
-
Create mass unit
|
93
|
-
|
94
|
-
kg = Unit.kg #=> #<Quantify::Unit::SI:0xb758b594 ... >
|
95
|
-
|
96
|
-
Create emission factor compound unit
|
97
|
-
|
98
|
-
kg_per_kWh = kg / kWh #=> #<Quantify::Unit::Compound:0xb746f093 ... >
|
99
|
-
kg_per_kWh.symbol #=> "kg_kW^-1_h^-1
|
100
|
-
kg_per_kWh.name #=> 'kilogram per kilowatt hour'
|
101
|
-
|
102
|
-
Create emission factor quantity
|
103
|
-
|
104
|
-
emission_factor = Quantity.new(0.54, kg_per_kWh) #=> #<Quantify::Quantity:0xb75cd570 ... >
|
105
|
-
emission_factor.to_s #=> "0.54 kg kW^-1 h^-1"
|
106
|
-
|
107
|
-
Create consumption quantity
|
108
|
-
|
109
|
-
consumption = Quantity.new(9885.5, kWh) #=> #<Quantify::Quantity:0xb7j4k3570 ... >
|
110
|
-
consumption.to_s #=> "9885.5 kWh"
|
151
|
+
other_unit = Unit.hour
|
152
|
+
other_unit.name => 'hour'
|
153
|
+
other_unit.symbol => 'h'
|
154
|
+
other_unit.measures => 'time'
|
155
|
+
other_unit.alternatives :symbol => [ 's', 'ks', 'Ms', 'Gs', 'Ts', 'd', 'min' ]
|
111
156
|
|
112
|
-
|
157
|
+
another_unit = unit / other_unit => <Quantify::Unit::Compound:0xb74af323 ... >
|
158
|
+
another_unit.name => 'kilometer per hour'
|
159
|
+
another_unit.symbol => 'km h^-1'
|
160
|
+
another_unit.measures => 'velocity'
|
161
|
+
another_unit.base_units.map(&:name) => ['kilogram','hour']
|
113
162
|
|
114
|
-
|
115
|
-
|
163
|
+
last_unit = Unit.m
|
164
|
+
last.unit.measures => 'length'
|
165
|
+
square = last_unit ** 2 => <Quantify::Unit::Compound:0xb446f12f ... >
|
166
|
+
square.symbol => 'm^2'
|
167
|
+
square.measures => 'area'
|
data/lib/quantify/dimensions.rb
CHANGED
@@ -76,7 +76,7 @@ module Quantify
|
|
76
76
|
if options[:physical_quantity]
|
77
77
|
@@dimensions << Dimensions.new(options)
|
78
78
|
else
|
79
|
-
raise InvalidDimensionError, "Cannot load dimensions without physical quantity description"
|
79
|
+
raise Exceptions::InvalidDimensionError, "Cannot load dimensions without physical quantity description"
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -122,10 +122,10 @@ module Quantify
|
|
122
122
|
end
|
123
123
|
return quantity.clone
|
124
124
|
else
|
125
|
-
raise InvalidArgumentError, "Physical quantity not known: #{name}"
|
125
|
+
raise Exceptions::InvalidArgumentError, "Physical quantity not known: #{name}"
|
126
126
|
end
|
127
127
|
else
|
128
|
-
raise InvalidArgumentError, "Argument must be a Symbol or String"
|
128
|
+
raise Exceptions::InvalidArgumentError, "Argument must be a Symbol or String"
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
@@ -202,9 +202,9 @@ module Quantify
|
|
202
202
|
if describe and not loaded?
|
203
203
|
@@dimensions << self
|
204
204
|
elsif describe
|
205
|
-
raise InvalidDimensionError, "A dimension instance with the same physical quantity already exists"
|
205
|
+
raise Exceptions::InvalidDimensionError, "A dimension instance with the same physical quantity already exists"
|
206
206
|
else
|
207
|
-
raise InvalidDimensionError, "Cannot load dimensions without physical quantity description"
|
207
|
+
raise Exceptions::InvalidDimensionError, "Cannot load dimensions without physical quantity description"
|
208
208
|
end
|
209
209
|
end
|
210
210
|
|
@@ -497,7 +497,7 @@ module Quantify
|
|
497
497
|
options.each_pair do |base_quantity,index|
|
498
498
|
base_quantity = base_quantity.to_s.downcase.to_sym
|
499
499
|
unless index.is_a? Integer and BASE_QUANTITIES.include? base_quantity
|
500
|
-
raise InvalidDimensionError, "An invalid base quantity was specified (#{base_quantity})"
|
500
|
+
raise Exceptions::InvalidDimensionError, "An invalid base quantity was specified (#{base_quantity})"
|
501
501
|
end
|
502
502
|
variable = "@#{base_quantity}"
|
503
503
|
if self.instance_variable_defined?(variable)
|
data/lib/quantify/exception.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
module Quantify
|
2
|
+
module Exceptions
|
2
3
|
|
3
|
-
|
4
|
-
|
4
|
+
class QuantityParseError < Exception
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
class InvalidObjectError < Exception
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
class InvalidUnitError < Exception
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
class InvalidDimensionError < Exception
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
class InvalidPhysicalQuantityError < Exception
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
+
class InvalidArgumentError < Exception
|
20
|
+
end
|
21
|
+
|
19
22
|
end
|
20
|
-
|
21
23
|
end
|
data/lib/quantify/quantity.rb
CHANGED
@@ -47,10 +47,10 @@ module Quantify
|
|
47
47
|
if quantity = /\A([\d\s.,]+)(\D+.*)\z/.match(string)
|
48
48
|
Quantity.new($1.strip, $2)
|
49
49
|
else
|
50
|
-
raise Quantify::QuantityParseError, "Cannot parse string into value and unit"
|
50
|
+
raise Quantify::Exceptions::QuantityParseError, "Cannot parse string into value and unit"
|
51
51
|
end
|
52
|
-
rescue Quantify::InvalidArgumentError
|
53
|
-
raise Quantify::QuantityParseError, "Cannot parse string into value and unit"
|
52
|
+
rescue Quantify::Exceptions::InvalidArgumentError
|
53
|
+
raise Quantify::Exceptions::QuantityParseError, "Cannot parse string into value and unit"
|
54
54
|
end
|
55
55
|
|
56
56
|
def self.configure &block
|
@@ -195,10 +195,10 @@ module Quantify
|
|
195
195
|
@value = value.send operator, other.value
|
196
196
|
return self
|
197
197
|
else
|
198
|
-
raise Quantify::InvalidObjectError "Cannot add or subtract Quantities with different dimensions"
|
198
|
+
raise Quantify::Exceptions::InvalidObjectError "Cannot add or subtract Quantities with different dimensions"
|
199
199
|
end
|
200
200
|
else
|
201
|
-
raise Quantify::InvalidObjectError "Cannot add or subtract non-Quantity objects"
|
201
|
+
raise Quantify::Exceptions::InvalidObjectError "Cannot add or subtract non-Quantity objects"
|
202
202
|
end
|
203
203
|
end
|
204
204
|
|
@@ -211,12 +211,12 @@ module Quantify
|
|
211
211
|
@value = value.send(operator,other.value)
|
212
212
|
return self
|
213
213
|
else
|
214
|
-
raise Quantify::InvalidArgumentError "Cannot multiply or divide a Quantity by a non-Quantity or non-Numeric object"
|
214
|
+
raise Quantify::Exceptions::InvalidArgumentError "Cannot multiply or divide a Quantity by a non-Quantity or non-Numeric object"
|
215
215
|
end
|
216
216
|
end
|
217
217
|
|
218
218
|
def pow!(power)
|
219
|
-
raise InvalidArgumentError, "Argument must be an integer" unless power.is_a? Integer
|
219
|
+
raise Exceptions::InvalidArgumentError, "Argument must be an integer" unless power.is_a? Integer
|
220
220
|
@value = value ** power
|
221
221
|
@unit = unit ** power
|
222
222
|
return self
|
@@ -267,7 +267,14 @@ module Quantify
|
|
267
267
|
|
268
268
|
def rationalize_units
|
269
269
|
return self unless unit.is_a? Unit::Compound
|
270
|
-
self.to unit.rationalize_base_units
|
270
|
+
self.to unit.clone.rationalize_base_units!
|
271
|
+
end
|
272
|
+
|
273
|
+
def rationalize_units!
|
274
|
+
rationalized_quantity = self.rationalize_units
|
275
|
+
@value = rationalized_quantity.value
|
276
|
+
@unit = rationalized_quantity.unit
|
277
|
+
return self
|
271
278
|
end
|
272
279
|
|
273
280
|
def cancel_base_units!(*units)
|
@@ -303,7 +310,7 @@ module Quantify
|
|
303
310
|
if object.kind_of? Numeric
|
304
311
|
return Quantity.new(object, Unit.unity), self
|
305
312
|
else
|
306
|
-
raise InvalidArgumentError, "Cannot coerce #{self.class} into #{object.class}"
|
313
|
+
raise Exceptions::InvalidArgumentError, "Cannot coerce #{self.class} into #{object.class}"
|
307
314
|
end
|
308
315
|
end
|
309
316
|
|
@@ -317,7 +324,7 @@ module Quantify
|
|
317
324
|
if method.to_s =~ /(to_)(.*)/
|
318
325
|
to($2)
|
319
326
|
else
|
320
|
-
|
327
|
+
super
|
321
328
|
end
|
322
329
|
end
|
323
330
|
|
@@ -110,7 +110,7 @@ module Quantify
|
|
110
110
|
elsif options[:dimensions].is_a? String or options[:dimensions].is_a? Symbol
|
111
111
|
@dimensions = Dimensions.for options[:dimensions]
|
112
112
|
else
|
113
|
-
raise InvalidArgumentError, "Unknown physical_quantity specified"
|
113
|
+
raise Exceptions::InvalidArgumentError, "Unknown physical_quantity specified"
|
114
114
|
end
|
115
115
|
@factor = options[:factor].nil? ? 1.0 : options[:factor].to_f
|
116
116
|
@symbol = options[:symbol].nil? ? nil : options[:symbol].standardize
|
@@ -145,7 +145,7 @@ module Quantify
|
|
145
145
|
#
|
146
146
|
def load
|
147
147
|
yield self if block_given?
|
148
|
-
raise InvalidArgumentError, "A unit with the same label: #{self.name}) already exists" if loaded?
|
148
|
+
raise Exceptions::InvalidArgumentError, "A unit with the same label: #{self.name}) already exists" if loaded?
|
149
149
|
Quantify::Unit.units << self if valid?
|
150
150
|
end
|
151
151
|
|
@@ -327,7 +327,7 @@ module Quantify
|
|
327
327
|
|
328
328
|
def valid?
|
329
329
|
return true if valid_descriptors? and valid_dimensions?
|
330
|
-
raise InvalidArgumentError, "Unit definition must include a name, a symbol, a label and physical quantity"
|
330
|
+
raise Exceptions::InvalidArgumentError, "Unit definition must include a name, a symbol, a label and physical quantity"
|
331
331
|
end
|
332
332
|
|
333
333
|
def valid_descriptors?
|
@@ -428,7 +428,7 @@ module Quantify
|
|
428
428
|
#
|
429
429
|
def with_prefix(name_or_symbol)
|
430
430
|
if self.name =~ /\A(#{valid_prefixes(:name).join("|")})/
|
431
|
-
raise InvalidArgumentError, "Cannot add prefix where one already exists: #{self.name}"
|
431
|
+
raise Exceptions::InvalidArgumentError, "Cannot add prefix where one already exists: #{self.name}"
|
432
432
|
end
|
433
433
|
|
434
434
|
prefix = Unit::Prefix.for(name_or_symbol,valid_prefixes)
|
@@ -442,7 +442,7 @@ module Quantify
|
|
442
442
|
new_unit_options[:physical_quantity] = self.dimensions
|
443
443
|
self.class.new(new_unit_options)
|
444
444
|
else
|
445
|
-
raise InvalidArgumentError, "Prefix unit is not known: #{prefix}"
|
445
|
+
raise Exceptions::InvalidArgumentError, "Prefix unit is not known: #{prefix}"
|
446
446
|
end
|
447
447
|
end
|
448
448
|
|
@@ -472,7 +472,7 @@ module Quantify
|
|
472
472
|
if object.kind_of? Numeric and object == 1
|
473
473
|
return Unit.unity, self
|
474
474
|
else
|
475
|
-
raise InvalidArgumentError, "Cannot coerce #{self.class} into #{object.class}"
|
475
|
+
raise Exceptions::InvalidArgumentError, "Cannot coerce #{self.class} into #{object.class}"
|
476
476
|
end
|
477
477
|
end
|
478
478
|
|
@@ -14,8 +14,8 @@ module Quantify
|
|
14
14
|
attr_accessor :unit, :index
|
15
15
|
|
16
16
|
def initialize(unit,index=1)
|
17
|
-
@unit = Unit.match(unit) || raise(InvalidUnitError, "Base unit not known: #{unit}")
|
18
|
-
raise InvalidUnitError, "Base unit cannot be compound unit" if @unit.is_a? Compound
|
17
|
+
@unit = Unit.match(unit) || raise(Exceptions::InvalidUnitError, "Base unit not known: #{unit}")
|
18
|
+
raise Exceptions::InvalidUnitError, "Base unit cannot be compound unit" if @unit.is_a? Compound
|
19
19
|
@index = index
|
20
20
|
end
|
21
21
|
|
@@ -32,7 +32,7 @@ module Quantify
|
|
32
32
|
# base units or just a subset - the numerator or denominator units.
|
33
33
|
#
|
34
34
|
def self.consolidate_base_units(base_units)
|
35
|
-
raise InvalidArgumentError, "Must provide an array of base units" unless base_units.is_a? Array
|
35
|
+
raise Exceptions::InvalidArgumentError, "Must provide an array of base units" unless base_units.is_a? Array
|
36
36
|
|
37
37
|
new_base_units = []
|
38
38
|
|
@@ -97,7 +97,7 @@ module Quantify
|
|
97
97
|
not unit.first.is_a? Compound and unit.size == 2
|
98
98
|
@base_units << CompoundBaseUnit.new(unit.first,unit.last)
|
99
99
|
else
|
100
|
-
raise InvalidArgumentError, "#{unit} does not represent a valid base unit"
|
100
|
+
raise Exceptions::InvalidArgumentError, "#{unit} does not represent a valid base unit"
|
101
101
|
end
|
102
102
|
end
|
103
103
|
@acts_as_alternative_unit = true
|
@@ -158,7 +158,7 @@ module Quantify
|
|
158
158
|
#
|
159
159
|
def cancel_base_units!(*units)
|
160
160
|
units.each do |unit|
|
161
|
-
raise InvalidArgumentError, "Cannot cancel by a compound unit" if unit.is_a? Unit::Compound
|
161
|
+
raise Exceptions::InvalidArgumentError, "Cannot cancel by a compound unit" if unit.is_a? Unit::Compound
|
162
162
|
unit = Unit.for unit unless unit.is_a? Unit::Base
|
163
163
|
|
164
164
|
numerator_unit = numerator_units.find { |base| unit == base.unit }
|
@@ -175,10 +175,10 @@ module Quantify
|
|
175
175
|
|
176
176
|
def rationalize_base_units!(scope=:partial,*units)
|
177
177
|
if scope == :full
|
178
|
-
Compound.rationalize_base_units(@base_units
|
178
|
+
Compound.rationalize_base_units(@base_units,*units)
|
179
179
|
else
|
180
|
-
Compound.rationalize_base_units(numerator_units
|
181
|
-
Compound.rationalize_base_units(denominator_units
|
180
|
+
Compound.rationalize_base_units(numerator_units,*units)
|
181
|
+
Compound.rationalize_base_units(denominator_units,*units)
|
182
182
|
end
|
183
183
|
consolidate_numerator_and_denominator_units!
|
184
184
|
end
|
data/lib/quantify/unit/unit.rb
CHANGED
@@ -60,7 +60,7 @@ module Quantify
|
|
60
60
|
unit = Unit.for unit
|
61
61
|
other_unit = Unit.for other_unit
|
62
62
|
unless unit.is_alternative_for? other_unit
|
63
|
-
raise InvalidUnitError, "Units do not represent the same physical quantity"
|
63
|
+
raise Exceptions::InvalidUnitError, "Units do not represent the same physical quantity"
|
64
64
|
end
|
65
65
|
new_unit = (unit / other_unit)
|
66
66
|
value = 1/new_unit.factor
|
@@ -94,7 +94,7 @@ module Quantify
|
|
94
94
|
( name_symbol_label_or_object.is_a?(String) and name_symbol_label_or_object.empty? )
|
95
95
|
name_symbol_or_label = name_symbol_label_or_object
|
96
96
|
unless name_symbol_or_label.is_a? String or name_symbol_or_label.is_a? Symbol
|
97
|
-
raise InvalidArgumentError, "Argument must be a Symbol or String"
|
97
|
+
raise Exceptions::InvalidArgumentError, "Argument must be a Symbol or String"
|
98
98
|
end
|
99
99
|
if unit = Unit.match(name_symbol_or_label)
|
100
100
|
return unit
|
@@ -102,7 +102,7 @@ module Quantify
|
|
102
102
|
if unit = Unit.parse(name_symbol_or_label)
|
103
103
|
return unit
|
104
104
|
end
|
105
|
-
rescue InvalidUnitError
|
105
|
+
rescue Exceptions::InvalidUnitError
|
106
106
|
return nil
|
107
107
|
end
|
108
108
|
|
@@ -111,7 +111,7 @@ module Quantify
|
|
111
111
|
def self.parse(string)
|
112
112
|
string = string.standardize
|
113
113
|
if string.scan(/(\/|per)/).size > 1
|
114
|
-
raise InvalidArgumentError, "Malformed unit: multiple uses of '/' or 'per'"
|
114
|
+
raise Exceptions::InvalidArgumentError, "Malformed unit: multiple uses of '/' or 'per'"
|
115
115
|
end
|
116
116
|
|
117
117
|
units = []
|
data/spec/quantity_spec.rb
CHANGED
@@ -246,5 +246,20 @@ describe Quantity do
|
|
246
246
|
quantity.unit.base_units.size.should == 1
|
247
247
|
quantity.to_s.should == "40.720412743579 inHg"
|
248
248
|
end
|
249
|
+
|
250
|
+
it "should rationalize units and return new quantity" do
|
251
|
+
quantity = 12.yards*36.feet
|
252
|
+
quantity.to_s.should eql "432.0 yd ft"
|
253
|
+
new_quantity=quantity.rationalize_units
|
254
|
+
quantity.to_s.should eql "432.0 yd ft"
|
255
|
+
new_quantity.to_s.should eql "144.0 yd^2"
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should rationalize units and modify value in place" do
|
259
|
+
quantity = 12.yards*36.feet
|
260
|
+
quantity.to_s.should eql "432.0 yd ft"
|
261
|
+
quantity.rationalize_units!
|
262
|
+
quantity.to_s.should eql "144.0 yd^2"
|
263
|
+
end
|
249
264
|
end
|
250
265
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quantify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 3
|
10
|
+
version: 1.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andrew Berkeley
|