ruby - Own class with spaceship operator does not work for LCS Diff -


i'm trying implement custom class including comparable mixin. later class used diff. class looks like

class element   include comparable   attr_reader :name    def initialize(name)     @name = name   end    def <=>(other)     @name <=> other.name   end end 

now test values 2 added entries compared a.

a = array.new b = array.new  a.push element.new('y1') a.push element.new('y2') a.push element.new('y4') a.push element.new('x1') a.push element.new('x2') a.push element.new('x4')  b.push element.new('y1') b.push element.new('y2') b.push element.new('y3') b.push element.new('y4') b.push element.new('x1') b.push element.new('x2') b.push element.new('x3') b.push element.new('x4') 

and run diff between both arrays

puts diff::lcs.diff(a, b).inspect 

i expect 2 added objects finds 8 changes... ideas why?

[[["-", 2, #<element:0x007fa9fb567898 @name="y4">],   ["-", 3, #<element:0x007fa9fbc69830 @name="x1">],   ["-", 4, #<element:0x007fa9fbca3378 @name="x2">],   ["+", 2, #<element:0x007fa9fb5e5e78 @name="y3">],   ["+", 3, #<element:0x007fa9fb606920 @name="y4">],   ["+", 4, #<element:0x007fa9fb625848 @name="x1">],   ["+", 5, #<element:0x007fa9fb647da8 @name="x2">],   ["+", 6, #<element:0x007fa9fbde8670 @name="x3">]]] 

if run test with

a = array.new b = array.new  a.push 'y1' a.push 'y2' a.push 'y4' a.push 'x1' a.push 'x2' a.push 'x4'  b.push 'y1' b.push 'y2' b.push 'y3' b.push 'y4' b.push 'x1' b.push 'x2' b.push 'x3' b.push 'x4' 

everything works expected:

[[["+", 2, "y3"]],  [["+", 6, "x3"]]] 

inspecting source of diff::lcs, elements in sequences used hash key.

the element class wrote mixed comparable module, got == method there. however, doesn't have eql? , hash method override, used hash determine key comparison.

with element class, have

irb(main):013:0> = element.new("a") => #<element:0x002ae4ce402da0 @name="a"> irb(main):014:0> b = element.new("a") => #<element:0x002ae4ce409ec0 @name="a"> irb(main):015:0> == b => true irb(main):016:0> a.eql? b => false irb(main):017:0> a.hash == b.hash => false irb(main):018:0> h = {} => {} irb(main):019:0> h[a] = 1 => 1 irb(main):020:0> h[b] => nil 

this affects lcs calculation.

the fix add eql? , hash method element class, think.

class element   include comparable   attr_reader :name    def initialize(name)     @name = name   end    def <=>(other)     @name <=> other.name   end    def eql? other     other.class == element , self.name == other.name   end    def hash     @name.hash ^ element.hash   end end 

Comments

Popular posts from this blog

c# - How to get the current UAC mode -

postgresql - Lazarus + Postgres: incomplete startup packet -

javascript - Ajax jqXHR.status==0 fix error -