Project

General

Profile

Actions

Bug #21376

open

Inconsistent equality between Sets with different compare_by_identity, different classes

Added by Ethan (Ethan -) 3 days ago. Updated 2 days ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 3.5.0dev (2025-05-26T17:42:35Z master 909a0daab6) +PRISM [x86_64-darwin22]
[ruby-core:122305]

Description

This is an inconsistency between the new core Set and the ruby-implemented Set. I think probably the new implementation's behavior seems correct and the ruby implementation is an incorrect edge case.

class MySet < Set
end

o = Object.new
Set.new([o]).compare_by_identity == MySet.new([o])
# => false on 3.5.0; true with the ruby implementation

My understanding is that, for Hash, if two hashes have unequal compare_by_identity? they are never equal (even if containing identical contents), unless both are empty. It would make sense for Set to be the same.

Hmm, analyzing the ruby Set#== a bit more, I see a further edge case where a non-identity set is considered equal to an identity set with as few as one element in common.

set_by_eq = Set.new(['a', 'b', 'c'])
# => #<Set: {"a", "b", "c"}>
set_by_id = MySet.new.compare_by_identity.merge(['a', 'a'.dup, 'a'.dup])
# => #<MySet: {"a", "a", "a"}>
set_by_eq == set_by_id
# => true in the ruby set, false in core set
set_by_id == set_by_eq
# => false in both

The latter seems unlikely it would ever be triggered unintentionally. The former I did happen across, but since I think the new behavior is correct, I will not be affected when I fix my code to consistently compare_by_identity. Given that, it may be questionable whether it's worth fixing.

Actions

Also available in: Atom PDF

Like0
Like0Like0