lib/ruby-units.rb in ruby-units-0.3.4 vs lib/ruby-units.rb in ruby-units-0.3.5

- old
+ new

@@ -1,10 +1,10 @@ require 'mathn' require 'rational' require 'date' require 'parsedate' -# = Ruby Units 0.3.3 +# = Ruby Units 0.3.5 # # Copyright 2006 by Kevin C. Olbrich, Ph.D. # # See http://rubyforge.org/ruby-units/ # @@ -38,11 +38,11 @@ # end # Unit.setup class Unit < Numeric require 'units' # pre-generate hashes from unit definitions for performance. - VERSION = '0.3.3' + VERSION = '0.3.5' @@USER_DEFINITIONS = {} @@PREFIX_VALUES = {} @@PREFIX_MAP = {} @@UNIT_MAP = {} @@UNIT_VALUES = {} @@ -128,10 +128,11 @@ @@OUTPUT_MAP[key]=value[0][0] end @@PREFIX_REGEX = @@PREFIX_MAP.keys.sort_by {|prefix| prefix.length}.reverse.join('|') @@UNIT_REGEX = @@UNIT_MAP.keys.sort_by {|unit| unit.length}.reverse.join('|') @@UNIT_MATCH_REGEX = /(#{@@PREFIX_REGEX})*?(#{@@UNIT_REGEX})\b/ + Unit.new(1) end include Comparable attr_accessor :scalar, :numerator, :denominator, :signature, :base_scalar, :base_numerator, :base_denominator, :output, :unit_name @@ -174,10 +175,15 @@ # "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 initialize(*options) + @scalar = nil + @base_scalar = nil + @unit_name = nil + @signature = nil + @output = nil if options.size == 2 begin cached = @@cached_units[options[1]] * options[0] copy(cached) rescue @@ -195,12 +201,10 @@ return end case 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] @@ -216,10 +220,12 @@ @denominator = UNITY_ARRAY when DateTime: @scalar = options[0].ajd @numerator = ['<day>'] @denominator = UNITY_ARRAY + when "": raise ArgumentError, "No Unit Specified" + when String: parse(options[0]) else raise ArgumentError, "Invalid Unit Format" end self.update_base_scalar self.replace_temperature @@ -230,27 +236,27 @@ @@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 - @scalar.freeze - @numerator.freeze - @denominator.freeze - @base_scalar.freeze - @signature.freeze - @is_base.freeze + [@scalar, @numerator, @denominator, @base_scalar, @signature, @is_base].each {|x| x.freeze} self end def kind return @@KINDS[self.signature] end def self.cached return @@cached_units end - + + def self.clear_cache + @@cached_units = {} + @@base_unit_cache = {} + end + def self.base_unit_cache return @@base_unit_cache end def to_unit @@ -323,14 +329,14 @@ if out return out else case target_units when :ft: - inches = self.to("in").scalar + inches = self.to("in").scalar.to_int out = "#{(inches / 12).truncate}\'#{(inches % 12).round}\"" when :lbs: - ounces = self.to("oz").scalar + ounces = self.to("oz").scalar.to_int out = "#{(ounces / 16).truncate} lbs, #{(ounces % 16).round} oz" when String begin #first try a standard format string target_units =~ /(%[\w\d#+-.]*)*\s*(.+)*/ out = $2 ? self.to($2).to_s($1) : "#{($1 || '%g') % @scalar || 0} #{self.units}".strip @@ -696,23 +702,25 @@ def floor Unit.new(@scalar.floor, @numerator, @denominator) end - # changes internal scalar to an integer, but retains the units # if unitless, returns an int def to_int - return @scalar.to_int if unitless? - Unit.new(@scalar.to_int, @numerator, @denominator) + return @scalar.to_int if self.unitless? + raise RuntimeError, 'Cannot convert to Integer, use Unit#scalar' end # Tries to make a Time object from current unit def to_time Time.at(self) end alias :time :to_time alias :to_i :to_int - alias :truncate :to_int + + def truncate + Unit.new(@scalar.truncate, @numerator, @denominator) + end def to_datetime DateTime.new(self.to('d').scalar) end