I ran into a similar issue that also surprised me. Below is an example of
it. It seems that the union operator ('|') uses object#id instead of
object#== to compare values. I understand the need for performance, but it
would be nice to be able to use == instead of comparing the id's.
irb(main):001:0> [1,2,3] | [3,4]
=> [1, 2, 3, 4]
irb(main):002:0> ["a","b","c"] | ["c","d"]
=> ["a", "b", "c", "d"]
irb(main):003:0> class A
irb(main):004:1> def initialize(x,y)
irb(main):005:2> @x,@y = x,y
irb(main):006:2> end
irb(main):007:1> def ==(other)
irb(main):008:2> @x == other.x && @y == other.y
irb(main):009:2> end
irb(main):010:1> end
=> nil
irb(main):011:0> class A
irb(main):012:1> attr_reader :x,:y
irb(main):013:1> end
=> nil
irb(main):014:0> [A.new(1,1), A.new(1,2)] | [A.new(1,2), A.new(1,3)]
=> [#<A:0x2810408 @y=1, @x=1>, #<A:0x28103f0 @y=2, @x=1>, #<A:0x2810390
@y=2, @x
=1>, #<A:0x2810318 @y=3, @x=1>]
irb(main):015:0>
Oddly though, if you do the same with strings, it doesn't double up on the
strings even though they have differing object id's. Why is that?
irb(main):001:0> a = "a"
=> "a"
irb(main):002:0> b = "b"
=> "b"
irb(main):003:0> b1 = "b"
=> "b"
irb(main):004:0> c = "c"
=> "c"
irb(main):005:0> [a, b] | [b1, c]
=> ["a", "b", "c"]
irb(main):006:0> b.id
=> 20682852
irb(main):007:0> b1.id
=> 20674092
Steve Tuckner
> -----Original Message-----
> From: Yukihiro Matsumoto [mailto:matz / ruby-lang.org]
> Sent: Thursday, February 20, 2003 1:18 PM
> To: ruby-talk ML
> Subject: Re: Inconsistent behavior in Array methods
>
>
> Hi,
>
> In message "Inconsistent behavior in Array methods"
> on 03/02/21, "Warren Brown" <wkb / airmail.net> writes:
>
> | I recently tracked down a bug in my code to a line that read:
> |
> | cards = cards.sort.uniq
> |
> | This seemed perfectly reasonable - the cards array contained Card
> |objects which were Enumerable. However, the bug was due to
> the fact that
> |Array#uniq does not use the object's == method to do
> comparisons - even
> |though Array#sort uses the object's <=> method. Upon
> investigation, I found
> |that the implementation of Array#uniq uses a hash, and since
> the key to the
> |hash is the object ID, uniqueness ends up being defined as
> (obj1.id ==
> |obj2.id). This was *surprising* to me.
>
> I know, but I thought the order of execution time was more important,
> especially for big arrays.
>
> matz.