🎃
[Bug #21376] Set を継承したオブジェクトを比較したときの挙動が Ruby 3.5 から変わっているというバグ報告
[Bug #21376] Inconsistent equality between Sets with different compare_by_identity, different classes
-
Set#compare_by_identityしたオブジェクトとSetを継承したオブジェクトを比較したときの挙動が Ruby 3.5 から変わっているというバグ報告
class MySet < Set
end
s1 = MySet.new([1]).compare_by_identity
s2 = Set.new([1])
pp s1 == s2
# Ruby 3.4 => true
# Ruby 3.5 => false
-
#compare_by_identityしているオブジェクトが逆の場合でも再現しますね - 逆に同じクラスのオブジェクトであれば再現はしない
- 一貫して
falseになる
- 一貫して
class MySet < Set
end
# Ruby 3.4 も 3.5 も false を返す
pp Set.new([1]).compare_by_identity == Set.new([1])
# => false
pp MySet.new([1]).compare_by_identity == MySet.new([1])
# => false
- これはそもそも Ruby 3.4 の挙動がバグみたいで Ruby 3.5 の挙動が正しいみたいですね
- ちなみに
Set#compare_by_identityはSetの要素の一致判定をオブジェクトの同一性で判定するように変更するようにするメソッド-
Hash#compare_by_identityと同じような動きになる - Hash#compare_by_identity (Ruby 3.4 リファレンスマニュアル)
-
s = Set.new
# 通常は同じ値の場合は重複しない
s << "a"
s << "a"
pp s
# => #<Set: {"a"}>
# compare_by_identity を呼ぶと object_id 等で比較するようになる
s.compare_by_identity
# なのでこの場合の "a" は別のオブジェクトとして Set に追加される
s << "a"
pp s
# => #<Set: {"a", "a"}>
Discussion