"Ben Tilly" <ben_tilly / hotmail.com> wrote:
>
>"Christoph Rippel" <crippel / primenet.com> wrote:
[much stuff, including 2 possible solutions to
the == issue for arrays]
Oops, both previous solutions had the major
defect that they were not commutative. But
this is solvable:
class Array
@@other_id = nil
@@other_seen = nil
def == (other)
if @@other_id.nil?
begin
@@other_id = Hash.new( nil )
@@other_seen = Hash.new( false )
return self == other
ensure
@other_id = nil
end
else
return false unless other.kind_of? Array
return false unless length == other.length
other_id = @@other_id[self.id]
if other_id.nil?
return false if @@other_seen[other.id]
@@other_seen[other.id] = true
@@other_id[self.id] = other.id
each_index do |i|
return false if not self[i] == other[i]
end
return true
else
return other_id == other.id
end
end
end
end
The key difference is the addition of the checks for
@@other_seen. If you don't have that, then you get
different results for this case:
a = ["hello"]
b = (1..3).map {|x| a}
c = (1..3).map {|x| ["hello"])
p (b == c)
p (c == b)
Note that currently Ruby says these are equal. With
the method above Ruby says that they are different.
Compare though what these two do:
b[0].push "world"
c[0].push "world"
I think that calling them unequal is quite reasonable.
Cheers,
Ben
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com