From abd81fded08b737cfbbfa1ac366d480924f273fe Mon Sep 17 00:00:00 2001 From: Dean Brundage Date: Sun, 3 Jun 2012 20:36:37 -0500 Subject: [PATCH 1/3] fix for #4 --- lib/quantity/unit.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/quantity/unit.rb b/lib/quantity/unit.rb index 0f060c6..a5e70fa 100644 --- a/lib/quantity/unit.rb +++ b/lib/quantity/unit.rb @@ -294,7 +294,7 @@ def calculate_value @dimension.numerators.each do | component | component.power.times do # we might have a unit for a compound dimension, such as liters for length^3. - value *= @units[Quantity::Dimension.for(component.dimension)].value + value *= @units[Quantity::Dimension.for(component.dimension)].value if @units[Quantity::Dimension.for(component.dimension)] end end @dimension.denominators.each do | component | From c7f19e390a90e8396ede94826371fcbb8e7fe0dc Mon Sep 17 00:00:00 2001 From: Dean Brundage Date: Fri, 27 Jul 2012 00:33:12 -0500 Subject: [PATCH 2/3] Supporting nil Quantity value Add compatible_with? --- lib/quantity.rb | 22 ++++++++++++++-------- lib/quantity/dimension.rb | 6 ++++++ lib/quantity/unit.rb | 6 ++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/lib/quantity.rb b/lib/quantity.rb index 2b416da..6f28b42 100644 --- a/lib/quantity.rb +++ b/lib/quantity.rb @@ -66,19 +66,19 @@ class Quantity # @option options [Symbol Unit] :unit Units # @return [Quantity] # - def initialize(value, unit = nil ) + def initialize(value = nil, unit = nil ) case value when Hash @unit = Unit.for(value[:unit]) @reference_value = value[:reference_value] || (value[:value] * @unit.value) @value = @unit.value_for(@reference_value) #dimension.reference.convert_proc(@unit).call(@reference_value) #@value = @unit.convert_proc(@unit).call(@reference_value) - when Numeric + when Numeric, String @unit = Unit.for(unit) if @unit.nil? @unit = Unit.from_string_form(unit) end - @value = value + @value = value.is_a?(Numeric) ? value : value.to_f @reference_value = value * @unit.value end end @@ -87,6 +87,7 @@ def initialize(value, unit = nil ) # @param [String] format Format for sprintf, will be given # @return [String] def to_s + return '' if value.nil? @unit.s_for(value) end @@ -133,10 +134,10 @@ def coerce(other) def +(other) if (other.is_a?(Numeric)) Quantity.new(@value + other, @unit) - elsif(other.is_a?(Quantity) && @unit.dimension == other.unit.dimension) + elsif compatible_with?(other) Quantity.new({:unit => @unit,:reference_value => @reference_value + other.reference_value}) else - raise ArgumentError,"Cannot add #{self} to #{other}" + raise ArgumentError,"Cannot add #{self} (#{@unit.dimension}) to #{other} (#{other.class}" + (other.is_a?(Quantity) ? "-#{other.unit.dimension})" : ')') end end @@ -147,10 +148,10 @@ def +(other) def -(other) if (other.is_a?(Numeric)) Quantity.new(@value - other, @unit) - elsif(other.is_a?(Quantity) && @unit.dimension == other.unit.dimension) + elsif compatible_with?(other) Quantity.new({:unit => @unit,:reference_value => @reference_value - other.reference_value}) else - raise ArgumentError, "Cannot subtract #{other} from #{self}" + raise ArgumentError, "Cannot subtract #{other} (#{other.class}) from #{self} (#{@unit.dimension})" end end @@ -161,7 +162,7 @@ def -(other) def <=>(other) if (other.is_a?(Numeric)) @value <=> other - elsif(other.is_a?(Quantity) && measures == other.measures) + elsif compatible_with?(other) @reference_value <=> other.reference_value else nil @@ -279,6 +280,11 @@ def to_f @value.to_f end + def compatible_with?(other) + return false if unit.nil? + other.respond_to?(:unit) && unit.compatible_with?(other.unit) + end + # Round this value to the nearest integer # @return [Quantity] def round diff --git a/lib/quantity/dimension.rb b/lib/quantity/dimension.rb index 325c20b..d7d64fc 100644 --- a/lib/quantity/dimension.rb +++ b/lib/quantity/dimension.rb @@ -178,6 +178,12 @@ def <=>(other) end end + + def compatible_with?(other) + self === other || (other.respond_to?(:name) && name == other.name) + end + + # Returns a developer-friendly representation of this value. # # The string will be of the format `#`, diff --git a/lib/quantity/unit.rb b/lib/quantity/unit.rb index a5e70fa..7994f3a 100644 --- a/lib/quantity/unit.rb +++ b/lib/quantity/unit.rb @@ -305,6 +305,12 @@ def calculate_value @value = value end + + def compatible_with?(other) + other.respond_to?(:dimension) && dimension.compatible_with?(other.dimension) + end + + # A vaguely human-readable form for this unit # @return [String] def string_form From 4a51b78d463bad6ba64ef735dec03f1d5cb5c35e Mon Sep 17 00:00:00 2001 From: Dean Brundage Date: Sun, 19 Aug 2012 16:29:48 -0500 Subject: [PATCH 3/3] no more nil quantities --- lib/quantity.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/quantity.rb b/lib/quantity.rb index 6f28b42..3fbfabf 100644 --- a/lib/quantity.rb +++ b/lib/quantity.rb @@ -66,7 +66,7 @@ class Quantity # @option options [Symbol Unit] :unit Units # @return [Quantity] # - def initialize(value = nil, unit = nil ) + def initialize(value, unit = nil ) case value when Hash @unit = Unit.for(value[:unit]) @@ -87,7 +87,6 @@ def initialize(value = nil, unit = nil ) # @param [String] format Format for sprintf, will be given # @return [String] def to_s - return '' if value.nil? @unit.s_for(value) end