Search code examples
rubyarraysoperator-overloadingsubtractioncomparison-operators

How does Array#- (subtract operator) compare elements for equality?


When I call Array#- it doesn't seems to call any comparison method on the strings I'm comparing:

class String
  def <=>(v)
    puts "#{self} <=> #{v}"
    super(v)
  end

  def ==(v)
    puts "#{self} == #{v}"
    super(v)
  end

  def =~(v)
    puts "#{self} =~ #{v}"
    super(v)
  end

  def ===(v)
    puts "#{self} == #{v}"
    super(v)
  end

  def eql?(v)
    puts "#{self}.eql? #{v}"
    super(v)
  end

  def equal?(v)
    puts "#{self}.equal? #{v}"
    super(v)
  end

  def hash()
    puts "#{self}.hash"
    super
  end
end

p %w{one two three} - %w{two}

It just returns:

["one", "three"]

So, what is Array#- doing?

Also, I'm using Ruby 1.9.2p290. In 1.8.7 it seems to cause an infinite loop.


Solution

  • source code for Array#-.

    It appears that rather than testing for equality, a hash is made from the second array. Anything not contained in that array is pushed into the resultant array.

    Array difference in 1.8.7 is implemented this way also. The changes to String only cause problems in irb (not in a plain ruby script).