lib/ruby-units.rb in ruby-units-0.3.3 vs lib/ruby-units.rb in ruby-units-0.3.4
- old
+ new
@@ -195,11 +195,12 @@
return
end
case options[0]
- when String: parse(options[0])
+ when "": raise ArgumentError, "No Unit Specified"
+ when String: parse(options[0])
when Hash:
@scalar = options[0][:scalar] || 1
@numerator = options[0][:numerator] || UNITY_ARRAY
@denominator = options[0][:denominator] || UNITY_ARRAY
@signature = options[0][:signature]
@@ -221,13 +222,13 @@
raise ArgumentError, "Invalid Unit Format"
end
self.update_base_scalar
self.replace_temperature
- unary_unit = self.units
+ unary_unit = self.units || ""
opt_units = options[0].scan(NUMBER_REGEX)[0][1] if String === options[0]
- unless @@cached_units.keys.include?(opt_units) || (opt_units =~ /(temp|deg)(C|K|R|F)/)
+ 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)|%/)
@@cached_units[opt_units] = (self.scalar == 1 ? self : opt_units.unit) if opt_units && !opt_units.empty?
end
unless @@cached_units.keys.include?(unary_unit) || (unary_unit =~ /(temp|deg)(C|K|R|F)/) then
@@cached_units[unary_unit] = (self.scalar == 1 ? self : unary_unit.unit)
end
@@ -781,10 +782,18 @@
def succ
raise ArgumentError, "Non Integer Scalar" unless @scalar == @scalar.to_i
q = @scalar.to_i.succ
Unit.new(q, @numerator, @denominator)
end
+
+ def coerce(other)
+ case other
+ when Unit : [other, self]
+ else
+ [Unit.new(other), self]
+ end
+ end
# Protected and Private Functions that should only be called from this class
protected
@@ -799,17 +808,10 @@
@signature = base.signature
end
end
- def coerce(other)
- case other
- when Unit : [other, self]
- else
- [Unit.new(other), self]
- end
- end
# calculates the unit signature vector used by unit_signature
def unit_signature_vector
return self.to_base.unit_signature_vector unless self.is_base?
@@ -925,17 +927,16 @@
# "1" -- creates a unitless constant with value 1
# "GPa" -- creates a unit with scalar 1 with units 'GPa'
# 6'4" -- recognized as 6 feet + 4 inches
# 8 lbs 8 oz -- recognized as 8 lbs + 8 ounces
def parse(passed_unit_string="0")
-
unit_string = passed_unit_string.dup
if unit_string =~ /\$\s*(#{NUMBER_REGEX})/
unit_string = "#{$1} USD"
end
- if unit_string =~ /(#{SCI_NUMBER})\s*%/
- unit_string = "#{$1} percent"
+ if unit_string =~ /(.+)%/
+ unit_string = "#{$1.to_f * 0.01}"
end
unit_string =~ NUMBER_REGEX
unit = @@cached_units[$2]
mult = ($1.empty? ? 1.0 : $1.to_f) rescue 1.0
@@ -945,27 +946,31 @@
@base_scalar *= mult
return self
end
unit_string.gsub!(/[<>]/,"")
-
+
# Special processing for unusual unit strings
# feet -- 6'5"
feet, inches = unit_string.scan(FEET_INCH_REGEX)[0]
if (feet && inches)
result = Unit.new("#{feet} ft") + Unit.new("#{inches} inches")
copy(result)
- return self
+ return #self
end
# weight -- 8 lbs 12 oz
pounds, oz = unit_string.scan(LBS_OZ_REGEX)[0]
if (pounds && oz)
result = Unit.new("#{pounds} lbs") + Unit.new("#{oz} oz")
copy(result)
- return self
+ return #self
end
+
+ raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized") if unit_string.count('/') > 1
+ raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized") if unit_string.scan(/\s\d+\S*/).size > 0
+
@scalar, top, bottom = unit_string.scan(UNIT_STRING_REGEX)[0] #parse the string into parts
top.scan(TOP_REGEX).each do |item|
n = item[1].to_i
x = "#{item[0]} "
@@ -981,11 +986,12 @@
@numerator ||= UNITY_ARRAY
@denominator ||= UNITY_ARRAY
@numerator = top.scan(@@UNIT_MATCH_REGEX).delete_if {|x| x.empty?}.compact if top
@denominator = bottom.scan(@@UNIT_MATCH_REGEX).delete_if {|x| x.empty?}.compact if bottom
us = "#{(top || '' + bottom || '')}".to_s.gsub(@@UNIT_MATCH_REGEX,'').gsub(/[\d\*, "'_^\/\$]/,'')
- raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized (#{us})") unless us.empty?
+
+ raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized") unless us.empty?
@numerator = @numerator.map do |item|
@@PREFIX_MAP[item[0]] ? [@@PREFIX_MAP[item[0]], @@UNIT_MAP[item[1]]] : [@@UNIT_MAP[item[1]]]
end.flatten.compact.delete_if {|x| x.empty?}
@@ -1040,10 +1046,14 @@
def inspect(raw = false)
return self.units_datetime_inspect if raw
self.to_s
end
+ def to_date
+ Date.civil(self.year, self.month, self.day)
+ end
+
end
class Object
def Unit(*other)
other.to_unit
@@ -1197,11 +1207,17 @@
Date.civil(1970,1,1)+(self.to_f+self.gmt_offset)/86400
end
def +(other)
case other
- when Unit: unit_add(other.to('s').scalar)
+ when Unit:
+ other = other.to('d').round.to('s') if ['y', 'decade', 'century'].include? other.units
+ begin
+ unit_add(other.to('s').scalar)
+ rescue RangeError
+ self.to_datetime + other
+ end
when DateTime: unit_add(other.to_time)
else
unit_add(other)
end
end
@@ -1212,10 +1228,17 @@
end
alias :unit_sub :-
def -(other)
case other
- when Unit: unit_sub(other.to('s').scalar)
+ when Unit:
+ other = other.to('d').round.to('s') if ['y', 'decade', 'century'].include? other.units
+ begin
+ unit_sub(other.to('s').scalar)
+ rescue RangeError
+ self.to_datetime - other
+ end
+
when DateTime: unit_sub(other.to_time)
else
unit_sub(other)
end
end