ruby-units 0.3.6 → 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +7 -0
- data/README.txt +9 -1
- data/lib/ruby-units.rb +24 -9
- data/lib/units.rb +1 -0
- data/test/test_ruby-units.rb +29 -10
- metadata +2 -2
data/CHANGELOG.txt
CHANGED
@@ -145,3 +145,10 @@ Change Log for Ruby-units
|
|
145
145
|
but only works properly for unitless Units.
|
146
146
|
|
147
147
|
2006-12-05 0.3.6 * Fixed bug where (unit/unit).ceil would fail
|
148
|
+
|
149
|
+
2006-12-14 0.3.7 * improved handling of percents and added a 'wt%' unit
|
150
|
+
equivalent to 1 g/dl.
|
151
|
+
* Improved handling for units with non-alphanumeric names
|
152
|
+
(like ' for feet, # for pound)
|
153
|
+
* Now you can enter durations as "HH:MM:SS, usec" or
|
154
|
+
"HH:MM:SS:usec"
|
data/README.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
=Ruby Units
|
2
2
|
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.7
|
4
4
|
|
5
5
|
Kevin C. Olbrich, Ph.D.
|
6
6
|
kevin.olbrich@gmail.com
|
@@ -115,6 +115,14 @@ Note: If you include the 'Chronic' gem, you can specify times in natural
|
|
115
115
|
'5 min'.before(Time.now)
|
116
116
|
'10 min'.ago
|
117
117
|
|
118
|
+
Durations may be entered as 'HH:MM:SS, usec' and will be returned in 'hours'.
|
119
|
+
|
120
|
+
'1:00'.unit #=> 1 h
|
121
|
+
'0:30'.unit #=> 0.5 h
|
122
|
+
'0:30:30'.unit #=> 0.5 h + 30 sec
|
123
|
+
|
124
|
+
If only one ":" is present, it is interpreted as the separator between hours and minutes.
|
125
|
+
|
118
126
|
==Ranges
|
119
127
|
|
120
128
|
[U('0 h')..U('10 h')].each {|x| p x}
|
data/lib/ruby-units.rb
CHANGED
@@ -2,7 +2,7 @@ require 'mathn'
|
|
2
2
|
require 'rational'
|
3
3
|
require 'date'
|
4
4
|
require 'parsedate'
|
5
|
-
# = Ruby Units 0.3.
|
5
|
+
# = Ruby Units 0.3.7
|
6
6
|
#
|
7
7
|
# Copyright 2006 by Kevin C. Olbrich, Ph.D.
|
8
8
|
#
|
@@ -40,7 +40,7 @@ require 'parsedate'
|
|
40
40
|
class Unit < Numeric
|
41
41
|
require 'units'
|
42
42
|
# pre-generate hashes from unit definitions for performance.
|
43
|
-
VERSION = '0.3.
|
43
|
+
VERSION = '0.3.7'
|
44
44
|
@@USER_DEFINITIONS = {}
|
45
45
|
@@PREFIX_VALUES = {}
|
46
46
|
@@PREFIX_MAP = {}
|
@@ -51,6 +51,7 @@ class Unit < Numeric
|
|
51
51
|
UNITY = '<1>'
|
52
52
|
UNITY_ARRAY= [UNITY]
|
53
53
|
FEET_INCH_REGEX = /(\d+)\s*(?:'|ft|feet)\s*(\d+)\s*(?:"|in|inches)/
|
54
|
+
TIME_REGEX = /(\d+)*:(\d+)*:*(\d+)*[:,]*(\d+)*/
|
54
55
|
LBS_OZ_REGEX = /(\d+)\s*(?:#|lbs|pounds)+[\s,]*(\d+)\s*(?:oz|ounces)/
|
55
56
|
SCI_NUMBER = %r{([+-]?\d*[.]?\d+(?:[Ee][+-]?)?\d*)}
|
56
57
|
NUMBER_REGEX = /#{SCI_NUMBER}*\s*(.+)?/
|
@@ -232,7 +233,7 @@ class Unit < Numeric
|
|
232
233
|
|
233
234
|
unary_unit = self.units || ""
|
234
235
|
opt_units = options[0].scan(NUMBER_REGEX)[0][1] if String === options[0]
|
235
|
-
unless @@cached_units.keys.include?(opt_units) || (opt_units =~ /(temp|deg(C|K|R|F))|(pounds|lbs[ ,]\d+ ounces|oz)|('\d+")|(ft|feet[ ,]\d+ in|inch|inches)
|
236
|
+
unless @@cached_units.keys.include?(opt_units) || (opt_units =~ /(temp|deg(C|K|R|F))|(pounds|lbs[ ,]\d+ ounces|oz)|('\d+")|(ft|feet[ ,]\d+ in|inch|inches)|%|(#{TIME_REGEX})/)
|
236
237
|
@@cached_units[opt_units] = (self.scalar == 1 ? self : opt_units.unit) if opt_units && !opt_units.empty?
|
237
238
|
end
|
238
239
|
unless @@cached_units.keys.include?(unary_unit) || (unary_unit =~ /(temp|deg)(C|K|R|F)/) then
|
@@ -946,9 +947,11 @@ class Unit < Numeric
|
|
946
947
|
if unit_string =~ /\$\s*(#{NUMBER_REGEX})/
|
947
948
|
unit_string = "#{$1} USD"
|
948
949
|
end
|
949
|
-
|
950
|
-
|
951
|
-
|
950
|
+
|
951
|
+
unit_string.gsub!(/%/,'percent')
|
952
|
+
unit_string.gsub!(/'/,'feet')
|
953
|
+
unit_string.gsub!(/"/,'inch')
|
954
|
+
unit_string.gsub!(/#/,'pound')
|
952
955
|
|
953
956
|
unit_string =~ NUMBER_REGEX
|
954
957
|
unit = @@cached_units[$2]
|
@@ -962,13 +965,25 @@ class Unit < Numeric
|
|
962
965
|
|
963
966
|
unit_string.gsub!(/[<>]/,"")
|
964
967
|
|
968
|
+
if unit_string =~ /:/
|
969
|
+
hours, minutes, seconds, microseconds = unit_string.scan(TIME_REGEX)[0]
|
970
|
+
raise ArgumentError, "Invalid Duration" if [hours, minutes, seconds, microseconds].all? {|x| x.nil?}
|
971
|
+
result = "#{hours || 0} h".unit +
|
972
|
+
"#{minutes || 0} minutes".unit +
|
973
|
+
"#{seconds || 0} seconds".unit +
|
974
|
+
"#{microseconds || 0} usec".unit
|
975
|
+
copy(result)
|
976
|
+
return
|
977
|
+
end
|
978
|
+
|
979
|
+
|
965
980
|
# Special processing for unusual unit strings
|
966
981
|
# feet -- 6'5"
|
967
982
|
feet, inches = unit_string.scan(FEET_INCH_REGEX)[0]
|
968
983
|
if (feet && inches)
|
969
984
|
result = Unit.new("#{feet} ft") + Unit.new("#{inches} inches")
|
970
985
|
copy(result)
|
971
|
-
return
|
986
|
+
return
|
972
987
|
end
|
973
988
|
|
974
989
|
# weight -- 8 lbs 12 oz
|
@@ -976,7 +991,7 @@ class Unit < Numeric
|
|
976
991
|
if (pounds && oz)
|
977
992
|
result = Unit.new("#{pounds} lbs") + Unit.new("#{oz} oz")
|
978
993
|
copy(result)
|
979
|
-
return
|
994
|
+
return
|
980
995
|
end
|
981
996
|
|
982
997
|
raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized") if unit_string.count('/') > 1
|
@@ -1002,7 +1017,7 @@ class Unit < Numeric
|
|
1002
1017
|
@denominator = bottom.scan(@@UNIT_MATCH_REGEX).delete_if {|x| x.empty?}.compact if bottom
|
1003
1018
|
us = "#{(top || '' + bottom || '')}".to_s.gsub(@@UNIT_MATCH_REGEX,'').gsub(/[\d\*, "'_^\/\$]/,'')
|
1004
1019
|
|
1005
|
-
raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized") unless us.empty?
|
1020
|
+
raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized ('#{us}' left '#{top =~ @@UNIT_MATCH_REGEX}')") unless us.empty?
|
1006
1021
|
|
1007
1022
|
@numerator = @numerator.map do |item|
|
1008
1023
|
@@PREFIX_MAP[item[0]] ? [@@PREFIX_MAP[item[0]], @@UNIT_MAP[item[1]]] : [@@UNIT_MAP[item[1]]]
|
data/lib/units.rb
CHANGED
@@ -132,6 +132,7 @@ UNIT_DEFINITIONS = {
|
|
132
132
|
|
133
133
|
#concentration
|
134
134
|
'<molar>' => [%w{M molar}, 1000, :concentration, %w{<mole>}, %w{<meter> <meter> <meter>}],
|
135
|
+
'<wtpercent>' => [%w{wt% wtpercent}, 10, :concentration, %w{<kilogram>}, %w{<meter> <meter> <meter>}],
|
135
136
|
|
136
137
|
#activity
|
137
138
|
'<katal>' => [%w{kat katal Katal}, 1.0, :activity, %w{<mole>}, %w{<second>}],
|
data/test/test_ruby-units.rb
CHANGED
@@ -141,9 +141,9 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
141
141
|
|
142
142
|
def test_to_base
|
143
143
|
unit1 = Unit.new("100 cm")
|
144
|
-
assert_in_delta 1,
|
144
|
+
assert_in_delta 1, unit1.to_base.scalar, 0.001
|
145
145
|
unit2 = Unit("1 mm^2 ms^-2")
|
146
|
-
assert_in_delta 1, 0.001
|
146
|
+
assert_in_delta 1, unit2.to_base.scalar, 0.001
|
147
147
|
end
|
148
148
|
|
149
149
|
def test_to_unit
|
@@ -154,16 +154,16 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
154
154
|
assert Unit === unit1
|
155
155
|
assert unit1 == unit2
|
156
156
|
unit1 = "2.54 cm".to_unit("in")
|
157
|
-
assert_in_delta 1, 0.001
|
157
|
+
assert_in_delta 1, unit1.scalar, 0.001
|
158
158
|
assert_equal ['<inch>'], unit1.numerator
|
159
159
|
unit1 = "2.54 cm".unit("in")
|
160
|
-
assert_in_delta 1,
|
160
|
+
assert_in_delta 1, unit1.scalar, 0.001
|
161
161
|
assert_equal ['<inch>'], unit1.numerator
|
162
162
|
unit1 = 1.unit
|
163
|
-
assert_in_delta 1,
|
163
|
+
assert_in_delta 1, unit1.scalar, 0.001
|
164
164
|
assert_equal ['<1>'], unit1.numerator
|
165
165
|
unit1 = [1,'mm'].unit
|
166
|
-
assert_in_delta 1,
|
166
|
+
assert_in_delta 1, unit1.scalar, 0.001
|
167
167
|
assert_equal ['<milli>','<meter>'], unit1.numerator
|
168
168
|
end
|
169
169
|
|
@@ -259,7 +259,7 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
259
259
|
assert_equal (a+b).units, 'mm'
|
260
260
|
assert_equal (b+a).scalar, 10
|
261
261
|
assert_equal (b+a).units, 'cm'
|
262
|
-
assert_in_delta
|
262
|
+
assert_in_delta (b+c).scalar, 12.54, 0.01
|
263
263
|
assert_equal (b+c).units, 'cm'
|
264
264
|
assert_raises(ArgumentError) {
|
265
265
|
a + d
|
@@ -276,7 +276,7 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
276
276
|
assert_equal (a-b).units, 'mm'
|
277
277
|
assert_equal (b-a).scalar, 10
|
278
278
|
assert_equal (b-a).units, 'cm'
|
279
|
-
assert_in_delta
|
279
|
+
assert_in_delta (b-c).scalar, 7.46, 0.01
|
280
280
|
assert_equal (b-c).units, 'cm'
|
281
281
|
assert_raises(ArgumentError) {
|
282
282
|
a - d
|
@@ -616,11 +616,17 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
616
616
|
def test_feet
|
617
617
|
unit1 = Unit.new("6'6\"")
|
618
618
|
assert_in_delta 6.5, unit1.scalar, 0.01
|
619
|
+
unit2 = "6'".unit
|
620
|
+
assert_equal unit2, '6 feet'.unit
|
621
|
+
unit3 = '6"'.unit
|
622
|
+
assert_equal unit3, '6 inch'.unit
|
623
|
+
|
619
624
|
end
|
620
625
|
|
621
626
|
def test_pounds
|
622
627
|
unit1 = Unit.new("8 pounds, 8 ounces")
|
623
628
|
assert_in_delta 8.5, unit1.scalar, 0.01
|
629
|
+
assert_equal '150#'.unit, '150 lbs'.unit
|
624
630
|
end
|
625
631
|
|
626
632
|
# these units are 'ambiguous' and could be mis-parsed
|
@@ -782,8 +788,9 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
782
788
|
}
|
783
789
|
a = '100 ml'.unit
|
784
790
|
b = '50%'.unit
|
785
|
-
c = a*b
|
786
|
-
|
791
|
+
c = a*b >> 'ml'
|
792
|
+
assert c =~ a
|
793
|
+
assert_in_delta '50 ml'.unit.scalar, c.scalar, 0.0001
|
787
794
|
end
|
788
795
|
|
789
796
|
def test_parse
|
@@ -815,5 +822,17 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
815
822
|
b = '10 mg/ml'.unit
|
816
823
|
assert_equal a/b, 1
|
817
824
|
end
|
825
|
+
|
826
|
+
def test_wt_percent
|
827
|
+
a = '1 wt%'.unit
|
828
|
+
b = '1 g/dl'.unit
|
829
|
+
assert_equal a,b
|
830
|
+
end
|
818
831
|
|
832
|
+
def test_parse_durations
|
833
|
+
assert_equal "1:00".unit, '1 hour'.unit
|
834
|
+
assert_equal "1:30".unit, "1.5 hour".unit
|
835
|
+
assert_equal "1:30:30".unit, "1.5 hour".unit + '30 sec'.unit
|
836
|
+
assert_equal "1:30:30,200".unit, "1.5 hour".unit + '30 sec'.unit + '200 usec'.unit
|
837
|
+
end
|
819
838
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ 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.3.
|
7
|
-
date: 2006-12-
|
6
|
+
version: 0.3.7
|
7
|
+
date: 2006-12-14 00:00:00 -05:00
|
8
8
|
summary: A model that performs unit conversions and unit math
|
9
9
|
require_paths:
|
10
10
|
- lib
|