Q:

How can I make the set difference insensitive to case?

I have a class in which the data is stored as a set and I want to be able to compare objects of that class such that the letter case of the elements is of no matter. For example if the set contains elements that are strings there should be no difference of "a" and "A".
To do this I have tried to define the eql? method of the set members to be insensitive to case but this has no effect on the method - (alias difference) in Set. So, how should I go about to make - insensitive to case?
The following code illustrates the problem:
require 'set'

class SomeSet
  include Enumerable

  def initialize; @elements = Set.new; end

  def add(o)
    @elements.add(o)
    self
  end

  def each(&block)              # To enable +Enumerable+
    @elements.each(&block)
  end

  def difference(compared_list)
    @elements - compared_list
  end
end

class Element
  attr_reader :element

  def initialize(element); @element = element; end

  # This seems to have no effect on +difference+
  def eql?(other_element)
    element.casecmp(other_element.element) == 0
  end
end

set1 = SomeSet.new
set2 = SomeSet.new
set1.add("a")
set2.add("A")

# The following turns out false but I want it to turn out true as case
# should not matter.
puts set1.difference(set2).empty?

A:

Ok, firstly, you're just storing strings from SomeSet#add, you need to store an instance of Element, like so:
def add(o)
  @elements.add(Element.new(o))
  self
end

And you need to implement a hash method in your Element class.
You can convert Element#@element to lowercase, and pass on its hash.
def hash
  element.downcase.hash
end

Full code and demo: http://codepad.org/PffThml2
Edit: For my O(n) insertion comment, above:
Insertions are O(1). From what I can see, eql? is only used with the hash of 2 elements is same. As we're doing hash on the downcased version of the element, it will be fairly well distributed, and eql? shouldn't be called much (if it is called at all).

