ruby-units 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -0
- data/lib/ruby-units.rb +42 -19
- data/test/test_ruby-units.rb +20 -0
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -130,3 +130,12 @@ Change Log for Ruby-units
|
|
130
130
|
Fixed a bug that would cause problems when adding
|
131
131
|
or subtracting units to a unit with a zero scalar.
|
132
132
|
* Date and DateTime objects can be converted to 'units'
|
133
|
+
|
134
|
+
2006-10-27 0.3.4 * Fixed a few more parsing bugs so that it will properly
|
135
|
+
complain about malformed units.
|
136
|
+
* Fixed a bug that prevents proper use of percents
|
137
|
+
* several minor tweaks
|
138
|
+
* some improved Date and DateTime handling
|
139
|
+
* can convert between Date, DateTime, and Time objects
|
140
|
+
* Time math will now return a DateTime if it goes out of
|
141
|
+
range.
|
data/lib/ruby-units.rb
CHANGED
@@ -197,7 +197,8 @@ class Unit < Numeric
|
|
197
197
|
|
198
198
|
|
199
199
|
case options[0]
|
200
|
-
when
|
200
|
+
when "": raise ArgumentError, "No Unit Specified"
|
201
|
+
when String: parse(options[0])
|
201
202
|
when Hash:
|
202
203
|
@scalar = options[0][:scalar] || 1
|
203
204
|
@numerator = options[0][:numerator] || UNITY_ARRAY
|
@@ -223,9 +224,9 @@ class Unit < Numeric
|
|
223
224
|
self.update_base_scalar
|
224
225
|
self.replace_temperature
|
225
226
|
|
226
|
-
unary_unit = self.units
|
227
|
+
unary_unit = self.units || ""
|
227
228
|
opt_units = options[0].scan(NUMBER_REGEX)[0][1] if String === options[0]
|
228
|
-
unless @@cached_units.keys.include?(opt_units) || (opt_units =~ /(temp|deg
|
229
|
+
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)|%/)
|
229
230
|
@@cached_units[opt_units] = (self.scalar == 1 ? self : opt_units.unit) if opt_units && !opt_units.empty?
|
230
231
|
end
|
231
232
|
unless @@cached_units.keys.include?(unary_unit) || (unary_unit =~ /(temp|deg)(C|K|R|F)/) then
|
@@ -783,6 +784,14 @@ class Unit < Numeric
|
|
783
784
|
q = @scalar.to_i.succ
|
784
785
|
Unit.new(q, @numerator, @denominator)
|
785
786
|
end
|
787
|
+
|
788
|
+
def coerce(other)
|
789
|
+
case other
|
790
|
+
when Unit : [other, self]
|
791
|
+
else
|
792
|
+
[Unit.new(other), self]
|
793
|
+
end
|
794
|
+
end
|
786
795
|
|
787
796
|
# Protected and Private Functions that should only be called from this class
|
788
797
|
protected
|
@@ -801,13 +810,6 @@ class Unit < Numeric
|
|
801
810
|
end
|
802
811
|
|
803
812
|
|
804
|
-
def coerce(other)
|
805
|
-
case other
|
806
|
-
when Unit : [other, self]
|
807
|
-
else
|
808
|
-
[Unit.new(other), self]
|
809
|
-
end
|
810
|
-
end
|
811
813
|
|
812
814
|
|
813
815
|
# calculates the unit signature vector used by unit_signature
|
@@ -927,13 +929,12 @@ class Unit < Numeric
|
|
927
929
|
# 6'4" -- recognized as 6 feet + 4 inches
|
928
930
|
# 8 lbs 8 oz -- recognized as 8 lbs + 8 ounces
|
929
931
|
def parse(passed_unit_string="0")
|
930
|
-
|
931
932
|
unit_string = passed_unit_string.dup
|
932
933
|
if unit_string =~ /\$\s*(#{NUMBER_REGEX})/
|
933
934
|
unit_string = "#{$1} USD"
|
934
935
|
end
|
935
|
-
if unit_string =~ /(
|
936
|
-
unit_string = "#{$1}
|
936
|
+
if unit_string =~ /(.+)%/
|
937
|
+
unit_string = "#{$1.to_f * 0.01}"
|
937
938
|
end
|
938
939
|
|
939
940
|
unit_string =~ NUMBER_REGEX
|
@@ -947,14 +948,14 @@ class Unit < Numeric
|
|
947
948
|
end
|
948
949
|
|
949
950
|
unit_string.gsub!(/[<>]/,"")
|
950
|
-
|
951
|
+
|
951
952
|
# Special processing for unusual unit strings
|
952
953
|
# feet -- 6'5"
|
953
954
|
feet, inches = unit_string.scan(FEET_INCH_REGEX)[0]
|
954
955
|
if (feet && inches)
|
955
956
|
result = Unit.new("#{feet} ft") + Unit.new("#{inches} inches")
|
956
957
|
copy(result)
|
957
|
-
return self
|
958
|
+
return #self
|
958
959
|
end
|
959
960
|
|
960
961
|
# weight -- 8 lbs 12 oz
|
@@ -962,8 +963,12 @@ class Unit < Numeric
|
|
962
963
|
if (pounds && oz)
|
963
964
|
result = Unit.new("#{pounds} lbs") + Unit.new("#{oz} oz")
|
964
965
|
copy(result)
|
965
|
-
return self
|
966
|
+
return #self
|
966
967
|
end
|
968
|
+
|
969
|
+
raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized") if unit_string.count('/') > 1
|
970
|
+
raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized") if unit_string.scan(/\s\d+\S*/).size > 0
|
971
|
+
|
967
972
|
@scalar, top, bottom = unit_string.scan(UNIT_STRING_REGEX)[0] #parse the string into parts
|
968
973
|
|
969
974
|
top.scan(TOP_REGEX).each do |item|
|
@@ -983,7 +988,8 @@ class Unit < Numeric
|
|
983
988
|
@numerator = top.scan(@@UNIT_MATCH_REGEX).delete_if {|x| x.empty?}.compact if top
|
984
989
|
@denominator = bottom.scan(@@UNIT_MATCH_REGEX).delete_if {|x| x.empty?}.compact if bottom
|
985
990
|
us = "#{(top || '' + bottom || '')}".to_s.gsub(@@UNIT_MATCH_REGEX,'').gsub(/[\d\*, "'_^\/\$]/,'')
|
986
|
-
|
991
|
+
|
992
|
+
raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized") unless us.empty?
|
987
993
|
|
988
994
|
@numerator = @numerator.map do |item|
|
989
995
|
@@PREFIX_MAP[item[0]] ? [@@PREFIX_MAP[item[0]], @@UNIT_MAP[item[1]]] : [@@UNIT_MAP[item[1]]]
|
@@ -1042,6 +1048,10 @@ class Date
|
|
1042
1048
|
self.to_s
|
1043
1049
|
end
|
1044
1050
|
|
1051
|
+
def to_date
|
1052
|
+
Date.civil(self.year, self.month, self.day)
|
1053
|
+
end
|
1054
|
+
|
1045
1055
|
end
|
1046
1056
|
|
1047
1057
|
class Object
|
@@ -1199,7 +1209,13 @@ class Time
|
|
1199
1209
|
|
1200
1210
|
def +(other)
|
1201
1211
|
case other
|
1202
|
-
when Unit:
|
1212
|
+
when Unit:
|
1213
|
+
other = other.to('d').round.to('s') if ['y', 'decade', 'century'].include? other.units
|
1214
|
+
begin
|
1215
|
+
unit_add(other.to('s').scalar)
|
1216
|
+
rescue RangeError
|
1217
|
+
self.to_datetime + other
|
1218
|
+
end
|
1203
1219
|
when DateTime: unit_add(other.to_time)
|
1204
1220
|
else
|
1205
1221
|
unit_add(other)
|
@@ -1214,7 +1230,14 @@ class Time
|
|
1214
1230
|
alias :unit_sub :-
|
1215
1231
|
def -(other)
|
1216
1232
|
case other
|
1217
|
-
when Unit:
|
1233
|
+
when Unit:
|
1234
|
+
other = other.to('d').round.to('s') if ['y', 'decade', 'century'].include? other.units
|
1235
|
+
begin
|
1236
|
+
unit_sub(other.to('s').scalar)
|
1237
|
+
rescue RangeError
|
1238
|
+
self.to_datetime - other
|
1239
|
+
end
|
1240
|
+
|
1218
1241
|
when DateTime: unit_sub(other.to_time)
|
1219
1242
|
else
|
1220
1243
|
unit_sub(other)
|
data/test/test_ruby-units.rb
CHANGED
@@ -776,5 +776,25 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
776
776
|
a = "1%".unit
|
777
777
|
b = "0.01%".unit
|
778
778
|
}
|
779
|
+
a = '100 ml'.unit
|
780
|
+
b = '50%'.unit
|
781
|
+
c = a*b
|
782
|
+
assert_equal '50 ml'.unit, c
|
783
|
+
end
|
784
|
+
|
785
|
+
def test_parse
|
786
|
+
assert_raises(ArgumentError) { "3 s/s/ft".unit }
|
787
|
+
assert_raises(ArgumentError) { "3 s**2|,s**2".unit }
|
788
|
+
assert_raises(ArgumentError) { "3 s**2 4s s**2".unit }
|
789
|
+
assert_raises(ArgumentError) { "3 s 5^6".unit }
|
790
|
+
assert_raises(ArgumentError) { "".unit }
|
791
|
+
end
|
792
|
+
|
793
|
+
def test_time_conversions
|
794
|
+
today = 'now'.to_time
|
795
|
+
assert_equal today,@april_fools
|
796
|
+
last_century = today - '150 years'.unit
|
797
|
+
assert_equal last_century.to_date, '1856-04-01'.to_date
|
798
|
+
|
779
799
|
end
|
780
800
|
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-10-
|
6
|
+
version: 0.3.4
|
7
|
+
date: 2006-10-27 00:00:00 -04:00
|
8
8
|
summary: A model that performs unit conversions and unit math
|
9
9
|
require_paths:
|
10
10
|
- lib
|