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 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