ruby-units 0.3.3 → 0.3.4
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 +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
|