0

データがセットとして格納されているクラスがあり、要素の大文字と小文字が関係ないように、そのクラスのオブジェクトを比較できるようにしたいと考えています。たとえば、セットに文字列である要素が含まれている場合、との違いはありませ"a""A"

これを行うためにeql?、大文字と小文字を区別しないようにsetメンバーのメソッドを定義しようとしましたが、これはSetのメソッド-(エイリアス)には影響しません。differenceでは、どうすれば-ケースに鈍感にすることができますか?

次のコードは問題を示しています。

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?
4

2 に答える 2

1

ドキュメントから:

要素の各対の等価性は、Object#eql? に従って決定されます。Set は Hash をストレージとして使用するため、Object#hash です。

おそらく、Object#hash も実装する必要があります。

require 'set'

class String2
  attr_reader :value

  def initialize v
    @value = v
  end

  def eql? v
    value.casecmp(v.value) == 0
  end

  def hash
    value.downcase.hash
  end
end

set1 = Set.new
set2 = Set.new
set1.add(String2.new "a")
set2.add(String2.new "A")

puts set1.difference(set2).empty?
于 2012-12-21T17:16:37.327 に答える