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
Post a Comment