From: "jeremyevans0 (Jeremy Evans)" Date: 2022-11-18T17:32:08+00:00 Subject: [ruby-core:110814] [Ruby master Bug#19113] Inconsistency in retention of compare_by_identity flag in Hash methods Issue #19113 has been updated by jeremyevans0 (Jeremy Evans). headius (Charles Nutter) wrote in #note-3: > jeremyevans0 (Jeremy Evans) wrote in #note-1: > > 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. > > I disagree. The contents of the other hash will have been populated using identity comparison rather than equality comparison. If that characteristic does not propagate to the new hash, any == keys will collide or else the set of keys will have to change. Is `Hash.[]` intended to make a copy, or a new hash populated with a subset of the original keys using non-identity, non-default semantics? It's explicitly documented as returning a new hash, not a copy: `Returns a new Hash object populated with the given objects`. The fact that it doesn't copy the default value/proc indicates to me that the compare_by_identity flag should not be copied either. However, I don't feel strongly regarding this. We can make it so the compare_by_identity flag is always copied. We do need to make some change, because the current behavior is inconsistent. ---------------------------------------- Bug #19113: Inconsistency in retention of compare_by_identity flag in Hash methods https://bugs.ruby-lang.org/issues/19113#change-100172 * 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: