ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:122305] [Ruby Bug#21376] Inconsistent equality between Sets with different compare_by_identity, different classes
@ 2025-05-27  6:47 Ethan (Ethan -) via ruby-core
  2025-05-27 15:46 ` [ruby-core:122314] " jeremyevans0 (Jeremy Evans) via ruby-core
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Ethan (Ethan -) via ruby-core @ 2025-05-27  6:47 UTC (permalink / raw)
  To: ruby-core; +Cc: Ethan (Ethan -)

Issue #21376 has been reported by Ethan (Ethan -).

----------------------------------------
Bug #21376: Inconsistent equality between Sets with different compare_by_identity, different classes
https://bugs.ruby-lang.org/issues/21376

* Author: Ethan (Ethan -)
* Status: Open
* ruby -v: ruby 3.5.0dev (2025-05-26T17:42:35Z master 909a0daab6) +PRISM [x86_64-darwin22]
* Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
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.

```ruby
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.

```ruby
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.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:122314] [Ruby Bug#21376] Inconsistent equality between Sets with different compare_by_identity, different classes
  2025-05-27  6:47 [ruby-core:122305] [Ruby Bug#21376] Inconsistent equality between Sets with different compare_by_identity, different classes Ethan (Ethan -) via ruby-core
@ 2025-05-27 15:46 ` jeremyevans0 (Jeremy Evans) via ruby-core
  2025-05-28  3:50 ` [ruby-core:122318] " Ethan (Ethan -) via ruby-core
  2025-06-05 13:31 ` [ruby-core:122455] " knu (Akinori MUSHA) via ruby-core
  2 siblings, 0 replies; 4+ messages in thread
From: jeremyevans0 (Jeremy Evans) via ruby-core @ 2025-05-27 15:46 UTC (permalink / raw)
  To: ruby-core; +Cc: jeremyevans0 (Jeremy Evans)

Issue #21376 has been updated by jeremyevans0 (Jeremy Evans).


This was reported as a bug. Can you explain what you think is the bug in the current core Set implementation?  From your description, it sounds like core Set fixed a bug in stdlib set.

----------------------------------------
Bug #21376: Inconsistent equality between Sets with different compare_by_identity, different classes
https://bugs.ruby-lang.org/issues/21376#change-113456

* Author: Ethan (Ethan -)
* Status: Open
* ruby -v: ruby 3.5.0dev (2025-05-26T17:42:35Z master 909a0daab6) +PRISM [x86_64-darwin22]
* Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
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.

```ruby
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.

```ruby
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.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:122318] [Ruby Bug#21376] Inconsistent equality between Sets with different compare_by_identity, different classes
  2025-05-27  6:47 [ruby-core:122305] [Ruby Bug#21376] Inconsistent equality between Sets with different compare_by_identity, different classes Ethan (Ethan -) via ruby-core
  2025-05-27 15:46 ` [ruby-core:122314] " jeremyevans0 (Jeremy Evans) via ruby-core
@ 2025-05-28  3:50 ` Ethan (Ethan -) via ruby-core
  2025-06-05 13:31 ` [ruby-core:122455] " knu (Akinori MUSHA) via ruby-core
  2 siblings, 0 replies; 4+ messages in thread
From: Ethan (Ethan -) via ruby-core @ 2025-05-28  3:50 UTC (permalink / raw)
  To: ruby-core; +Cc: Ethan (Ethan -)

Issue #21376 has been updated by Ethan (Ethan -).


I am not certain what behavior is intended as correct - the 3.5 one seems correct to me but I am no expert. Then assuming the 3.5 behavior is correct, don't know if backporting a fix to supported versions with ruby Set is desirable. If it's not worth backporting, close the issue, I have no problem with that.


----------------------------------------
Bug #21376: Inconsistent equality between Sets with different compare_by_identity, different classes
https://bugs.ruby-lang.org/issues/21376#change-113459

* Author: Ethan (Ethan -)
* Status: Open
* ruby -v: ruby 3.5.0dev (2025-05-26T17:42:35Z master 909a0daab6) +PRISM [x86_64-darwin22]
* Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
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.

```ruby
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.

```ruby
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.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:122455] [Ruby Bug#21376] Inconsistent equality between Sets with different compare_by_identity, different classes
  2025-05-27  6:47 [ruby-core:122305] [Ruby Bug#21376] Inconsistent equality between Sets with different compare_by_identity, different classes Ethan (Ethan -) via ruby-core
  2025-05-27 15:46 ` [ruby-core:122314] " jeremyevans0 (Jeremy Evans) via ruby-core
  2025-05-28  3:50 ` [ruby-core:122318] " Ethan (Ethan -) via ruby-core
@ 2025-06-05 13:31 ` knu (Akinori MUSHA) via ruby-core
  2 siblings, 0 replies; 4+ messages in thread
From: knu (Akinori MUSHA) via ruby-core @ 2025-06-05 13:31 UTC (permalink / raw)
  To: ruby-core; +Cc: knu (Akinori MUSHA)

Issue #21376 has been updated by knu (Akinori MUSHA).


This bug in optimization in Set#== deserves to be fixed, I think.  In hindsight, adding Set#compare_by_identity might not have been the best idea.

----------------------------------------
Bug #21376: Inconsistent equality between Sets with different compare_by_identity, different classes
https://bugs.ruby-lang.org/issues/21376#change-113640

* Author: Ethan (Ethan -)
* Status: Open
* ruby -v: ruby 3.5.0dev (2025-05-26T17:42:35Z master 909a0daab6) +PRISM [x86_64-darwin22]
* Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
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.

```ruby
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.

```ruby
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.



-- 
https://bugs.ruby-lang.org/
______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-06-05 13:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-05-27  6:47 [ruby-core:122305] [Ruby Bug#21376] Inconsistent equality between Sets with different compare_by_identity, different classes Ethan (Ethan -) via ruby-core
2025-05-27 15:46 ` [ruby-core:122314] " jeremyevans0 (Jeremy Evans) via ruby-core
2025-05-28  3:50 ` [ruby-core:122318] " Ethan (Ethan -) via ruby-core
2025-06-05 13:31 ` [ruby-core:122455] " knu (Akinori MUSHA) via ruby-core

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).