diff --git a/lib/ruby_units/unit.rb b/lib/ruby_units/unit.rb index e059d5ae..350fe358 100644 --- a/lib/ruby_units/unit.rb +++ b/lib/ruby_units/unit.rb @@ -71,7 +71,7 @@ class Unit < Numeric :substance, :luminosity, :currency, - :memory, + :information, :angle ] @@KINDS = { @@ -120,7 +120,7 @@ class Unit < Numeric 63999998 => :illuminance, 64000000 => :luminous_power, 1280000000 => :currency, - 25600000000 => :memory, + 25600000000 => :information, 511999999980 => :angular_velocity, 512000000000 => :angle } @@ -1048,9 +1048,8 @@ def as_json(*args) # returns the 'unit' part of the Unit object without the scalar # @return [String] - def units + def units(with_prefix = true) return "" if @numerator == UNITY_ARRAY && @denominator == UNITY_ARRAY - return @unit_name unless @unit_name.nil? output_numerator = [] output_denominator = [] num = @numerator.clone.compact @@ -1061,7 +1060,9 @@ def units else while defn = RubyUnits::Unit.definition(num.shift) do if defn && defn.prefix? - output_numerator << defn.display_name + RubyUnits::Unit.definition(num.shift).display_name + if with_prefix + output_numerator << (defn.display_name + RubyUnits::Unit.definition(num.shift).display_name) + end else output_numerator << defn.display_name end @@ -1073,7 +1074,9 @@ def units else while defn = RubyUnits::Unit.definition(den.shift) do if defn && defn.prefix? - output_denominator << defn.display_name + RubyUnits::Unit.definition(den.shift).display_name + if with_prefix + output_denominator << (defn.display_name + RubyUnits::Unit.definition(den.shift).display_name) + end else output_denominator << defn.display_name end @@ -1087,7 +1090,6 @@ def units map { |x| [x, output_denominator.count(x)] }. map { |element, power| ("#{element}".strip + (power > 1 ? "^#{power}" : '')) } out = "#{on.join('*')}#{od.empty? ? '' : '/' + od.join('*')}".strip - @unit_name = out unless self.kind == :temperature return out end @@ -1264,6 +1266,16 @@ def coerce(other) end end + # returns a new unit that has been + def best_prefix + _best_prefix = if (self.kind == :information) + @@PREFIX_VALUES.key(2**((Math.log(self.base_scalar,2) / 10.0).floor * 10)) + else + @@PREFIX_VALUES.key(10**((Math.log10(self.base_scalar) / 3.0).floor * 3)) + end + self.to(RubyUnits::Unit.new(@@PREFIX_MAP.key(_best_prefix)+self.units(false))) + end + # Protected and Private Functions that should only be called from this class protected @@ -1300,6 +1312,7 @@ def unit_signature_vector return vector end + private # used by #dup to duplicate a Unit @@ -1516,8 +1529,6 @@ def self.base_units return @@base_units ||= @@definitions.dup.delete_if { |_, defn| !defn.base? }.keys.map { |u| RubyUnits::Unit.new(u) } end - private - # parse a string consisting of a number and a unit string # @param [String] string # @return [Array] consisting of [Numeric, "unit"] diff --git a/lib/ruby_units/unit_definitions/base.rb b/lib/ruby_units/unit_definitions/base.rb index 952cc238..36a1eff7 100644 --- a/lib/ruby_units/unit_definitions/base.rb +++ b/lib/ruby_units/unit_definitions/base.rb @@ -61,7 +61,7 @@ unit.scalar = 1 unit.numerator = %w{} unit.aliases = %w{B byte bytes} - unit.kind = :memory + unit.kind = :information end RubyUnits::Unit.define("dollar") do |unit| diff --git a/spec/ruby-units/unit_spec.rb b/spec/ruby-units/unit_spec.rb index e0501b0c..8cd39ce2 100644 --- a/spec/ruby-units/unit_spec.rb +++ b/spec/ruby-units/unit_spec.rb @@ -1306,6 +1306,11 @@ specify { Unit('23 m').div(Unit('2 m')).should == 11 } end + context '#best_prefix' do + specify { Unit('1024 KiB').best_prefix.should == Unit('1 MiB')} + specify { Unit('1000 m').best_prefix.should == Unit('1 km')} + end + context "Time helper functions" do before do Time.stub!(:now).and_return(Time.utc(2011,10,16))