# Re: Question about the Set class, XOR, and arrays

From: Daniel B. [mailto:[email protected]]

irb(main):003:0> Set[1,2,3] ^ [3,4,5,5]
=> #<Set: {1, 2, 4}>

What?! I’m confused. Do I need a refresher in Set theory or something?

Looks like a bug due to Set#^'s implementation that assumes that the
enumerable passed in has each item only once (or, due to the
implementation, an odd number of times).

irb(main):001:0> require ‘set’
=> true
irb(main):002:0> a = Set[1,2,3]
=> #<Set: {1, 2, 3}>
irb(main):003:0> a ^ [3,4,5]
=> #<Set: {5, 1, 2, 4}>
irb(main):004:0> a ^ [3,4,5,5]
=> #<Set: {1, 2, 4}>
irb(main):005:0> a ^ [3,4,5,5,5]
=> #<Set: {5, 1, 2, 4}>

The first time it sees “5”, it adds it to the resulting set. The second
time it sees 5, it says “Oh, I already have a 5 in the result, better
remove it.”

def ^(enum)
enum.is_a?(Enumerable) or raise ArgumentError, “value must be
enumerable”
n = dup
enum.each { |o| if n.include?(o) then n.delete(o) else n.add(o) end
}
n
end

Use #uniq on the array to get a proper answer:

irb(main):006:0> a ^ [3,4,5,5].uniq
=> #<Set: {5, 1, 2, 4}>

Hi,

At Thu, 2 Nov 2006 05:32:11 +0900,
Gavin K. wrote:

irb(main):001:0> require ‘set’
The first time it sees “5”, it adds it to the resulting set. The second
time it sees 5, it says “Oh, I already have a 5 in the result, better
remove it.”

I’ll commit the following fix which I think is smaller and faster.
Thanks!

# Index: set.rb

RCS file: /src/ruby/lib/set.rb,v
retrieving revision 1.30
diff -u -u -r1.30 set.rb
— set.rb 2 Nov 2006 00:21:26 -0000 1.30
+++ set.rb 2 Nov 2006 05:32:23 -0000
@@ -294,8 +294,8 @@

# ((set | enum) - (set & enum)).

def ^(enum)

• n = dup
• enum.each { |o| if n.include?(o) then n.delete(o) else n.add(o) end
}
• n = Set.new(enum)
• each { |o| if n.include?(o) then n.delete(o) else n.add(o) end }
n
end

/
/__ __ Akinori.org / MUSHA.org
/ ) ) ) ) / FreeBSD.org / Ruby-lang.org
Akinori MUSHA aka / (_ / ( (__( @ iDaemons.org / and.or.jp

“Different eyes see different things,
Different hearts beat on different strings –
But there are times for you and me when all such things agree”