ruby-units 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +15 -0
- data/lib/{ruby_units.rb → ruby-units.rb} +43 -17
- data/test/{test_ruby_units.rb → test_ruby-units.rb} +128 -6
- metadata +5 -4
data/CHANGELOG
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Change Log for Ruby-units
|
2
|
+
=========================
|
3
|
+
2006-08-22 0.1.0 * Initial Release
|
4
|
+
2006-08-22 0.1.1 * Added new format option "1 mm".to_unit("in") now converts the result to the indicated units
|
5
|
+
* Fixed some naming issues so that the gem name matches the require name.
|
6
|
+
* Added CHANGELOG
|
7
|
+
* Improved test coverage (100% code coverage via RCov)
|
8
|
+
* fixed a bug that prevented units with a prefix in the denominator from converting properly
|
9
|
+
* can use .unit method on a string to create a new unit object
|
10
|
+
* can now coerce or define units from arrays, strings, numerics.
|
11
|
+
"1 mm".unit + [1, 'mm'] === "2 mm".unit
|
12
|
+
[1,'mm','s'].unit === "1 mm/s".unit
|
13
|
+
2.5.unit === "2.5".unit
|
14
|
+
* Added instructions on how to add custom units
|
15
|
+
|
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
# = Ruby Units
|
1
|
+
# = Ruby Units 0.1.1
|
3
2
|
#
|
4
3
|
# Copyright 2006 by Kevin C. Olbrich, Ph.D.
|
5
4
|
#
|
@@ -11,7 +10,7 @@
|
|
11
10
|
#
|
12
11
|
# See README for detailed usage instructions and examples
|
13
12
|
#
|
14
|
-
#
|
13
|
+
# ==Unit Definition Format
|
15
14
|
#
|
16
15
|
# '<name>' => [%w{prefered_name synonyms}, conversion_to_base, :classification, %w{<base> <units> <in> <numerator>} , %w{<base> <units> <in> <denominator>} ],
|
17
16
|
#
|
@@ -26,8 +25,14 @@
|
|
26
25
|
# This package covers nearly all SI, Imperial, and units commonly used
|
27
26
|
# in the United States. If your favorite units are not listed here, send me an email
|
28
27
|
#
|
29
|
-
#
|
30
|
-
#
|
28
|
+
# To add / override a unit definition, add a code block like this..
|
29
|
+
#
|
30
|
+
# class Unit < Numeric
|
31
|
+
# UNIT_DEFINITIONS = {
|
32
|
+
# <name>' => [%w{prefered_name synonyms}, conversion_to_base, :classification, %w{<base> <units> <in> <numerator>} , %w{<base> <units> <in> <denominator>} ]
|
33
|
+
# }
|
34
|
+
# end
|
35
|
+
# Unit.setup
|
31
36
|
class Unit < Numeric
|
32
37
|
require 'units'
|
33
38
|
# pre-generate hashes from unit definitions for performance.
|
@@ -77,14 +82,16 @@ class Unit < Numeric
|
|
77
82
|
# 8 lbs 8 oz -- recognized as 8 lbs + 8 ounces
|
78
83
|
#
|
79
84
|
def initialize(options)
|
80
|
-
|
81
|
-
|
82
|
-
|
85
|
+
case options
|
86
|
+
when String: parse(options)
|
87
|
+
when Hash:
|
83
88
|
@quantity = options[:quantity] || 1
|
84
89
|
@numerator = options[:numerator] || ["<1>"]
|
85
90
|
@denominator = options[:denominator] || []
|
91
|
+
when Array: parse("#{options[0]} #{options[1]}/#{options[2]}")
|
92
|
+
when Numeric: parse(options.to_s)
|
86
93
|
else
|
87
|
-
raise ArgumentError, "
|
94
|
+
raise ArgumentError, "Invalid Unit Format"
|
88
95
|
end
|
89
96
|
self.update_base_quantity
|
90
97
|
self.unit_signature
|
@@ -120,16 +127,16 @@ class Unit < Numeric
|
|
120
127
|
den << @@UNIT_VALUES[Regexp.escape(unit)][:denominator] if @@UNIT_VALUES[Regexp.escape(unit)] && @@UNIT_VALUES[Regexp.escape(unit)][:denominator]
|
121
128
|
end
|
122
129
|
end
|
123
|
-
|
124
130
|
@denominator.each do |unit|
|
125
|
-
if @@
|
126
|
-
q /= @@
|
131
|
+
if @@PREFIX_VALUES[Regexp.escape(unit)]
|
132
|
+
q /= @@PREFIX_VALUES[Regexp.escape(unit)]
|
127
133
|
else
|
128
134
|
q /= @@UNIT_VALUES[Regexp.escape(unit)][:quantity] if @@UNIT_VALUES[Regexp.escape(unit)]
|
129
135
|
den << @@UNIT_VALUES[Regexp.escape(unit)][:numerator] if @@UNIT_VALUES[Regexp.escape(unit)] && @@UNIT_VALUES[Regexp.escape(unit)][:numerator]
|
130
136
|
num << @@UNIT_VALUES[Regexp.escape(unit)][:denominator] if @@UNIT_VALUES[Regexp.escape(unit)] && @@UNIT_VALUES[Regexp.escape(unit)][:denominator]
|
131
137
|
end
|
132
138
|
end
|
139
|
+
|
133
140
|
num = num.flatten.compact
|
134
141
|
den = den.flatten.compact
|
135
142
|
num = ['<1>'] if num.empty?
|
@@ -497,8 +504,10 @@ class Unit < Numeric
|
|
497
504
|
case other
|
498
505
|
when Unit : [other, self]
|
499
506
|
when String : [Unit.new(other), self]
|
507
|
+
when Array: [Unit.new(other.join('*')), self]
|
508
|
+
when Numeric : [Unit.new(other.to_s), self]
|
500
509
|
else
|
501
|
-
|
510
|
+
raise ArgumentError, "Invalid Unit Definition"
|
502
511
|
end
|
503
512
|
end
|
504
513
|
|
@@ -587,10 +596,27 @@ end
|
|
587
596
|
|
588
597
|
class Object
|
589
598
|
def Unit(other)
|
590
|
-
|
599
|
+
other.to_unit
|
591
600
|
end
|
592
|
-
|
593
|
-
|
594
|
-
|
601
|
+
end
|
602
|
+
|
603
|
+
class Numeric
|
604
|
+
def to_unit(other = nil)
|
605
|
+
other ? Unit.new(self.to_s) >> other : Unit.new(self.to_s)
|
606
|
+
end
|
607
|
+
alias :unit :to_unit
|
608
|
+
end
|
609
|
+
|
610
|
+
class Array
|
611
|
+
def to_unit(other = nil)
|
612
|
+
other ? Unit.new("#{self[0]} #{self[1]}/#{self[2]}") >> other : Unit.new("#{self[0]} #{self[1]}/#{self[2]}")
|
613
|
+
end
|
614
|
+
alias :unit :to_unit
|
615
|
+
end
|
616
|
+
|
617
|
+
class String
|
618
|
+
def to_unit(other = nil)
|
619
|
+
other ? Unit.new(self) >> other : Unit.new(self)
|
595
620
|
end
|
621
|
+
alias :unit :to_unit
|
596
622
|
end
|
@@ -1,13 +1,22 @@
|
|
1
1
|
require 'test/unit'
|
2
|
-
require '
|
2
|
+
require 'ruby-units'
|
3
3
|
|
4
4
|
class Unit < Numeric
|
5
|
-
@@USER_DEFINITIONS = {'<inchworm>' => [%w{inworm inchworm}, 0.0254, :length, %w{<meter>} ]
|
5
|
+
@@USER_DEFINITIONS = {'<inchworm>' => [%w{inworm inchworm}, 0.0254, :length, %w{<meter>} ],
|
6
|
+
'<habenero>' => [%{degH}, 100, :temperature, %w{<celcius>}]}
|
6
7
|
Unit.setup
|
7
8
|
end
|
8
9
|
|
9
10
|
class TestRubyUnit < Test::Unit::TestCase
|
10
11
|
|
12
|
+
def test_clone
|
13
|
+
unit1= "1 mm".unit
|
14
|
+
unit2 = unit1.clone
|
15
|
+
assert_not_equal unit1.numerator.object_id, unit2.numerator.object_id
|
16
|
+
assert_not_equal unit1.denominator.object_id, unit2.denominator.object_id
|
17
|
+
assert unit1 === unit2
|
18
|
+
end
|
19
|
+
|
11
20
|
def test_unary_minus
|
12
21
|
unit1 = Unit.new("1 mm")
|
13
22
|
unit2 = Unit.new("-1 mm")
|
@@ -27,7 +36,9 @@ class TestRubyUnit < Test::Unit::TestCase
|
|
27
36
|
|
28
37
|
def test_to_base
|
29
38
|
unit1 = Unit.new("100 cm")
|
30
|
-
|
39
|
+
assert_in_delta 1, 0.001, unit1.to_base.quantity
|
40
|
+
unit2 = Unit("1 mm^2 ms^-2")
|
41
|
+
assert_in_delta 1, 0.001, unit2.to_base.quantity
|
31
42
|
end
|
32
43
|
|
33
44
|
def test_to_unit
|
@@ -36,6 +47,18 @@ class TestRubyUnit < Test::Unit::TestCase
|
|
36
47
|
unit2 = Unit("1 mm")
|
37
48
|
assert Unit === unit1
|
38
49
|
assert unit1 == unit2
|
50
|
+
unit1 = "2.54 cm".to_unit("in")
|
51
|
+
assert_in_delta 1, 0.001, unit1.quantity
|
52
|
+
assert_equal ['<inch>'], unit1.numerator
|
53
|
+
unit1 = "2.54 cm".unit("in")
|
54
|
+
assert_in_delta 1, 0.001, unit1.quantity
|
55
|
+
assert_equal ['<inch>'], unit1.numerator
|
56
|
+
unit1 = 1.unit
|
57
|
+
assert_in_delta 1, 0.001, unit1.quantity
|
58
|
+
assert_equal ['<1>'], unit1.numerator
|
59
|
+
unit1 = [1,'mm'].unit
|
60
|
+
assert_in_delta 1, 0.001, unit1.quantity
|
61
|
+
assert_equal ['<milli>','<meter>'], unit1.numerator
|
39
62
|
end
|
40
63
|
|
41
64
|
def test_create_unitless
|
@@ -91,6 +114,20 @@ class TestRubyUnit < Test::Unit::TestCase
|
|
91
114
|
assert_equal ['<second>','<second>'],unit1.denominator
|
92
115
|
end
|
93
116
|
|
117
|
+
def test_create_from_array
|
118
|
+
unit1 = Unit.new([1, "mm^2", "ul^2"])
|
119
|
+
assert_equal 1, unit1.to_f
|
120
|
+
assert_equal ['<milli>','<meter>','<milli>','<meter>'], unit1.numerator
|
121
|
+
assert_equal ['<micro>','<liter>','<micro>','<liter>'], unit1.denominator
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_bad_create
|
125
|
+
assert_raises(ArgumentError) { Unit.new(nil)}
|
126
|
+
assert_raises(ArgumentError) { Unit.new(true)}
|
127
|
+
assert_raises(ArgumentError) { Unit.new(false)}
|
128
|
+
assert_raises(ArgumentError) { Unit.new(/(.+)/)}
|
129
|
+
end
|
130
|
+
|
94
131
|
def test_convert
|
95
132
|
unit1 = Unit.new("1 attoparsec/microfortnight")
|
96
133
|
assert_nothing_raised {
|
@@ -115,6 +152,15 @@ class TestRubyUnit < Test::Unit::TestCase
|
|
115
152
|
assert_raises(ArgumentError) { unit3= unit1 >> 5.0}
|
116
153
|
end
|
117
154
|
|
155
|
+
def test_compare
|
156
|
+
unit1 = "1 mm".unit
|
157
|
+
unit2 = "1 mm".unit
|
158
|
+
unit3 = unit2 >> "in"
|
159
|
+
assert unit1 === unit2
|
160
|
+
assert !(unit1 === unit3)
|
161
|
+
assert unit1 === "1 mm"
|
162
|
+
end
|
163
|
+
|
118
164
|
def test_matched_units
|
119
165
|
unit1 = Unit.new("1 m*kg/s")
|
120
166
|
unit2 = Unit.new("1 in*pound/min")
|
@@ -178,6 +224,47 @@ class TestRubyUnit < Test::Unit::TestCase
|
|
178
224
|
assert_raise(ArgumentError) {(unit1+unit2).to_f}
|
179
225
|
end
|
180
226
|
|
227
|
+
def test_add_coerce
|
228
|
+
unit1 = "1 mm".unit
|
229
|
+
assert_nothing_raised {
|
230
|
+
unit2 = unit1 + "1 mm"
|
231
|
+
assert_equal "2 mm".unit, unit2
|
232
|
+
}
|
233
|
+
assert_nothing_raised {
|
234
|
+
unit2 = unit1 + [1,"mm"]
|
235
|
+
assert_equal "2 mm".unit, unit2
|
236
|
+
}
|
237
|
+
assert_nothing_raised {
|
238
|
+
unit2 = "1".unit + 1
|
239
|
+
assert_equal "2".unit, unit2
|
240
|
+
}
|
241
|
+
assert_raises(ArgumentError) {
|
242
|
+
unit2 = "1".unit + nil
|
243
|
+
}
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_subtract_coerce
|
247
|
+
unit1 = "1 mm".unit
|
248
|
+
assert_nothing_raised {
|
249
|
+
unit2 = unit1 - "1 mm"
|
250
|
+
assert_equal "0 mm".unit, unit2
|
251
|
+
}
|
252
|
+
end
|
253
|
+
def test_multiply_coerce
|
254
|
+
unit1 = "1 mm".unit
|
255
|
+
assert_nothing_raised {
|
256
|
+
unit2 = unit1 * "1 mm"
|
257
|
+
assert_equal "1 mm^2".unit, unit2
|
258
|
+
}
|
259
|
+
end
|
260
|
+
def test_divide_coerce
|
261
|
+
unit1 = "1 mm".unit
|
262
|
+
assert_nothing_raised {
|
263
|
+
unit2 = unit1 / "1 mm"
|
264
|
+
assert_equal "1".unit, unit2
|
265
|
+
}
|
266
|
+
end
|
267
|
+
|
181
268
|
def test_signature #"1 m s deg K kg A mol cd byte rad
|
182
269
|
unit1 = Unit.new("1 m*s*degK*kg*A*mol*cd*byte*rad*dollar")
|
183
270
|
assert_equal unit1.signature, (0..9).inject(0) {|product, n| product + 20**n}
|
@@ -198,11 +285,11 @@ class TestRubyUnit < Test::Unit::TestCase
|
|
198
285
|
end
|
199
286
|
|
200
287
|
def test_multiply
|
201
|
-
unit1 = Unit.new("1
|
202
|
-
unit2 = Unit.new("
|
288
|
+
unit1 = Unit.new("1 m/ms")
|
289
|
+
unit2 = Unit.new("1 m/ms")
|
203
290
|
assert_nothing_raised {
|
204
291
|
unit3 = unit1 * unit2
|
205
|
-
assert_equal Unit.new("
|
292
|
+
assert_equal Unit.new("1 m^2/ms^2"), unit3
|
206
293
|
}
|
207
294
|
end
|
208
295
|
|
@@ -313,6 +400,41 @@ class TestRubyUnit < Test::Unit::TestCase
|
|
313
400
|
assert_in_delta 558.27, unit2.to_f, 0.01
|
314
401
|
unit3 = Unit.new("1 J/degC")
|
315
402
|
assert_in_delta 1, (unit3 >> "J/degK").to_f, 0.01
|
403
|
+
assert_raises(ArgumentError) {unit1 >> "degH"}
|
404
|
+
|
405
|
+
unit1 = Unit.new("98.6 degF")
|
406
|
+
unit2 = unit1 >> "degC"
|
407
|
+
assert_in_delta 37, unit2.to_f, 0.1
|
408
|
+
unit2 = unit1 >> "degK"
|
409
|
+
assert_in_delta 310.15, unit2.to_f, 0.01
|
410
|
+
unit2 = unit1 >> "degR"
|
411
|
+
assert_in_delta 558.27, unit2.to_f, 0.01
|
412
|
+
unit3 = Unit.new("1 J/degC")
|
413
|
+
assert_in_delta 1, (unit3 >> "J/degK").to_f, 0.01
|
414
|
+
assert_raises(ArgumentError) {unit1 >> "degH"}
|
415
|
+
|
416
|
+
unit1 = Unit.new("310.15 degK")
|
417
|
+
unit2 = unit1 >> "degF"
|
418
|
+
assert_in_delta 98.6, unit2.to_f, 0.1
|
419
|
+
unit2 = unit1 >> "degC"
|
420
|
+
assert_in_delta 37, unit2.to_f, 0.01
|
421
|
+
unit2 = unit1 >> "degR"
|
422
|
+
assert_in_delta 558.27, unit2.to_f, 0.01
|
423
|
+
unit3 = Unit.new("1 J/degC")
|
424
|
+
assert_in_delta 1, (unit3 >> "J/degK").to_f, 0.01
|
425
|
+
assert_raises(ArgumentError) {unit1 >> "degH"}
|
426
|
+
|
427
|
+
unit1 = Unit.new("558.27 degR")
|
428
|
+
unit2 = unit1 >> "degC"
|
429
|
+
assert_in_delta 37, unit2.to_f, 0.1
|
430
|
+
unit2 = unit1 >> "degK"
|
431
|
+
assert_in_delta 310.15, unit2.to_f, 0.01
|
432
|
+
unit2 = unit1 >> "degF"
|
433
|
+
assert_in_delta 98.6, unit2.to_f, 0.01
|
434
|
+
unit3 = Unit.new("1 J/degC")
|
435
|
+
assert_in_delta 1, (unit3 >> "J/degK").to_f, 0.01
|
436
|
+
assert_raises(ArgumentError) {unit1 >> "degH"}
|
437
|
+
assert_raises(ArgumentError) {"10 degH".unit >> "degH"}
|
316
438
|
end
|
317
439
|
|
318
440
|
def test_feet
|
metadata
CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ruby-units
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.
|
6
|
+
version: 0.1.1
|
7
7
|
date: 2006-08-22 00:00:00 -04:00
|
8
8
|
summary: A model that performs unit conversions and unit math
|
9
9
|
require_paths:
|
@@ -31,11 +31,12 @@ authors:
|
|
31
31
|
files:
|
32
32
|
- LICENSE
|
33
33
|
- README
|
34
|
-
-
|
34
|
+
- CHANGELOG
|
35
|
+
- lib/ruby-units.rb
|
35
36
|
- lib/units.rb
|
36
|
-
- test/
|
37
|
+
- test/test_ruby-units.rb
|
37
38
|
test_files:
|
38
|
-
- test/
|
39
|
+
- test/test_ruby-units.rb
|
39
40
|
rdoc_options: []
|
40
41
|
|
41
42
|
extra_rdoc_files: []
|