From: "jeremyevans0 (Jeremy Evans)" <noreply@...>
Date: 2022-11-09T20:21:06+00:00
Subject: [ruby-core:110672] [Ruby master Bug#19113] Inconsistency in retention of compare_by_identity flag in Hash methods

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


I think the following behavior makes the most sense:

* `Hash.[]` should never retain the compare_by_identity flag.  It doesn't copy the default value/proc, so retaining the compare_by_identity flag does not make sense.
* `Hash.ruby2_keywords_hash` should always retain the compare_by_identity flag.  It copies the default value/proc, so retaining the compare_by_identity flag makes sense.
* `Hash#compact` should copy the default value/proc and retain the compare_by_identity flag.  It currently does neither.  However, the documentation says it returns a copy of the receiver, which implies the result should have the same default value/proc and compare_by_identity flag as the receiver.

I've submitted a pull request for these changes: https://github.com/ruby/ruby/pull/6702

----------------------------------------
Bug #19113: Inconsistency in retention of compare_by_identity flag in Hash methods
https://bugs.ruby-lang.org/issues/19113#change-100014

* Author: jeremyevans0 (Jeremy Evans)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.2.0dev (2022-11-07T17:29:28Z master 9001e53e68) [x86_64-openbsd7.2]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
`Hash.[]` and `Hash.ruby2_keywords_hash` retain the compare_by_identity flag for non-empty hashes, but do not retain it for empty hashes:

```ruby
hs = [{}.compare_by_identity, {:a=>1}.compare_by_identity]
hs.map{|h| Hash[h].compare_by_identity?}
# => [false, true]
hs.map{|h| Hash.ruby2_keywords_hash(h).compare_by_identity?}
# => [false, true]
```

This inconsistency seems like a bug.

`Hash#compact` always drops the compare_by_identity flag, but it is documented as returning a copy of self, implying the compare_by_identity flag is kept (since #dup and #clone retain the flag).

```ruby
{}.compare_by_identity.compact.compare_by_identity?
# => false
```

I'm not sure whether is a bug, because it is consistent, but I think retaining the flag makes more sense.

I'll try to work on a fix for both of these issues tomorrow.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>