From 1b50268e63daf165096caeda1328a5ea7bf648bd Mon Sep 17 00:00:00 2001 From: Kevin Olbrich Date: Wed, 1 Jan 2014 16:09:05 -0500 Subject: [PATCH 1/4] unitless units are only equivalent if they use the same unit name. This prevents unitless units from incorrectly being detected as equivalent to unrelated units. --- lib/ruby_units/unit.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ruby_units/unit.rb b/lib/ruby_units/unit.rb index 61cfb482..6730d9cf 100644 --- a/lib/ruby_units/unit.rb +++ b/lib/ruby_units/unit.rb @@ -633,6 +633,8 @@ def ==(other) case when other.respond_to?(:zero?) && other.zero? return self.zero? + when self.unitless? && other.instance_of?(Unit) && other.unitless? + return self.units == other.units when other.instance_of?(Unit) return false unless self =~ other return self.base_scalar == other.base_scalar From 9307413cbb790915b0b263572e9c0b3f73872b93 Mon Sep 17 00:00:00 2001 From: Kevin Olbrich Date: Wed, 1 Jan 2014 16:19:54 -0500 Subject: [PATCH 2/4] add specs and fix check... unitless? is not the right check for counting units --- lib/ruby_units/unit.rb | 2 +- spec/ruby-units/unit_spec.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/ruby_units/unit.rb b/lib/ruby_units/unit.rb index 6730d9cf..de76bc7a 100644 --- a/lib/ruby_units/unit.rb +++ b/lib/ruby_units/unit.rb @@ -633,7 +633,7 @@ def ==(other) case when other.respond_to?(:zero?) && other.zero? return self.zero? - when self.unitless? && other.instance_of?(Unit) && other.unitless? + when self.kind == :unitless && other.instance_of?(Unit) && other.kind == :unitless return self.units == other.units when other.instance_of?(Unit) return false unless self =~ other diff --git a/spec/ruby-units/unit_spec.rb b/spec/ruby-units/unit_spec.rb index 11001598..2ea33f2e 100644 --- a/spec/ruby-units/unit_spec.rb +++ b/spec/ruby-units/unit_spec.rb @@ -1438,3 +1438,12 @@ specify { ((p*v)/(n*r)).convert_to('tempK').should be_within(Unit("0.1 degK")).of(Unit("12027.2 tempK")) } end end + +describe 'comparing counting units' do + specify { Unit.new('3 dB').should_not eq(Unit.new('3 sr')) } + specify { Unit.new('3 sr').should_not eq(Unit.new('3 nt')) } + specify { Unit.new('3 nt').should_not eq(Unit.new('3 bp')) } + specify { Unit.new('3 bp').should_not eq(Unit.new('3 molecule')) } + specify { Unit.new('3 molecule').should_not eq(Unit.new('3 each')) } + specify { Unit.new('3 each').should_not eq(Unit.new('3')) } +end From d101fe3bff5cfe1d7c33b035d910230d0a6ae4f8 Mon Sep 17 00:00:00 2001 From: Kevin Olbrich Date: Wed, 1 Jan 2014 16:30:08 -0500 Subject: [PATCH 3/4] add 'counting?' check for units, related to issue #67 --- lib/ruby_units/unit.rb | 6 ++++++ spec/ruby-units/unit_spec.rb | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/ruby_units/unit.rb b/lib/ruby_units/unit.rb index de76bc7a..ca23c3ac 100644 --- a/lib/ruby_units/unit.rb +++ b/lib/ruby_units/unit.rb @@ -598,6 +598,12 @@ def unitless? return(@numerator == UNITY_ARRAY && @denominator == UNITY_ARRAY) end + # returns true if this is a counting unit + # @return [Boolean] + def counting? + self.kind == :unitless && !self.unitless? + end + # Compare two Unit objects. Throws an exception if they are not of compatible types. # Comparisons are done based on the value of the unit in base SI units. # @param [Object] other diff --git a/spec/ruby-units/unit_spec.rb b/spec/ruby-units/unit_spec.rb index 2ea33f2e..9b4b7356 100644 --- a/spec/ruby-units/unit_spec.rb +++ b/spec/ruby-units/unit_spec.rb @@ -24,6 +24,7 @@ it { should_not be_degree } it { should be_base } it { should be_unitless } + it { should_not be_counting } it { should be_zero } its(:base) { should == subject } end @@ -40,6 +41,7 @@ it { should_not be_degree } it { should be_base } it { should be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should == subject } end @@ -56,6 +58,7 @@ it { should_not be_degree } it { should be_base } it { should be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should == subject } end @@ -72,6 +75,7 @@ it { should_not be_degree } it { should be_base } it { should be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should == subject } end @@ -88,6 +92,7 @@ it { should_not be_degree } it { should be_base } it { should be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should == subject } end @@ -104,6 +109,7 @@ it { should_not be_degree } it { should be_base } it { should be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should == subject } end @@ -119,6 +125,7 @@ it { should_not be_degree } it { should be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should == subject } end @@ -135,6 +142,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should == Unit("0.001 m") } end @@ -151,6 +159,7 @@ it { should_not be_degree } it { should be_base } it { should be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should == Unit("1") } end @@ -167,6 +176,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should == Unit("0.001 m") } end @@ -183,6 +193,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should == Unit("1 kg*m^2/s^2") } end @@ -198,6 +209,7 @@ it { should_not be_degree } it { should be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should == Unit("10 m/s^2") } end @@ -212,6 +224,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_within(Unit("0.01 m")).of Unit("1.6764 m") } specify { subject.to_s(:ft).should == %{5'6"} } @@ -227,6 +240,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_within(Unit("0.01 kg")).of Unit("2.8633 kg") } specify { subject.to_s(:lbs).should == "6 lbs, 5 oz" } @@ -242,6 +256,7 @@ it { should be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_within(Unit("0.01 degK")).of Unit("373.15 tempK") } its(:temperature_scale) { should == "degC" } @@ -257,6 +272,7 @@ it { should_not be_degree } it { should be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_a(Numeric) } its(:temperature_scale) { should be_nil } @@ -272,6 +288,7 @@ it { should be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } its(:base) { should be_within(Unit("0.01 degK")).of Unit("100 degK") } end @@ -285,6 +302,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should be_counting } it { should_not be_zero } its(:base) { should be_a(Numeric) } its(:temperature_scale) { should be_nil } @@ -300,6 +318,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_a(Numeric) } its(:temperature_scale) { should be_nil } @@ -315,6 +334,7 @@ it { should_not be_degree } it { should be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_a Numeric } its(:temperature_scale) { should be_nil } @@ -330,6 +350,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should be_counting } it { should_not be_zero } its(:base) { should be_a Numeric } its(:temperature_scale) { should be_nil } @@ -345,6 +366,7 @@ it { should_not be_degree } it { should be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_a Numeric } its(:temperature_scale) { should be_nil } @@ -360,6 +382,7 @@ it { should_not be_degree } it { should be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_a Numeric } its(:temperature_scale) { should be_nil } @@ -376,6 +399,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_a Numeric } its(:temperature_scale) { should be_nil } @@ -392,6 +416,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_a Numeric } its(:temperature_scale) { should be_nil } @@ -407,6 +432,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_a Numeric } its(:temperature_scale) { should be_nil } @@ -423,6 +449,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_a Numeric } its(:temperature_scale) { should be_nil } @@ -437,6 +464,7 @@ it { should_not be_degree } it { should be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_a Numeric } its(:temperature_scale) { should be_nil } @@ -451,6 +479,7 @@ it { should_not be_degree } it { should be_base } it { should_not be_unitless } + it { should_not be_counting } it { should_not be_zero } its(:base) { should be_a Numeric } its(:temperature_scale) { should be_nil } @@ -467,6 +496,7 @@ it { should_not be_degree } it { should_not be_base } it { should_not be_unitless } + it { should be_counting } it { should_not be_zero } its(:base) { should be_a Numeric } its(:temperature_scale) { should be_nil } From 19942e4ee19585b6cdd28a9faf7284e835ef52e7 Mon Sep 17 00:00:00 2001 From: Kevin Olbrich Date: Wed, 1 Jan 2014 16:37:24 -0500 Subject: [PATCH 4/4] make counting and unitless units incompatible --- lib/ruby_units/unit.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ruby_units/unit.rb b/lib/ruby_units/unit.rb index ca23c3ac..aa588603 100644 --- a/lib/ruby_units/unit.rb +++ b/lib/ruby_units/unit.rb @@ -639,7 +639,7 @@ def ==(other) case when other.respond_to?(:zero?) && other.zero? return self.zero? - when self.kind == :unitless && other.instance_of?(Unit) && other.kind == :unitless + when self.counting? && other.instance_of?(Unit) && other.counting? return self.units == other.units when other.instance_of?(Unit) return false unless self =~ other @@ -666,7 +666,7 @@ def ==(other) def =~(other) case other when Unit - self.signature == other.signature + self.signature == other.signature && self.counting? == other.counting? else begin x, y = coerce(other)