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 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 String: parse(options[0])
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)(C|K|R|F)/)
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 =~ /(#{SCI_NUMBER})\s*%/
936
- unit_string = "#{$1} percent"
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
- raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized (#{us})") unless us.empty?
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: unit_add(other.to('s').scalar)
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: unit_sub(other.to('s').scalar)
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)
@@ -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.3
7
- date: 2006-10-05 00:00:00 -04:00
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