"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