[ruby-core:103078] [Ruby master Bug#17757] Hash#slice does not keep compare_by_identity on the results
From:
marcandre-ruby-core@...
Date:
2021-03-28 19:33:08 UTC
List:
ruby-core #103078
Issue #17757 has been updated by marcandre (Marc-Andre Lafortune).
I should have looked into this when I checked #16996.
Looks like we have behavior that is all over the place, and the same method sometimes returns a hash with different comparability depending if the receiver is empty or not...
```
ruby 3.1.0dev (2021-03-28T18:18:08Z master 1cdecb4349) [x86_64-darwin18]
slice with arg: false
slice without arg: false
except with arg: true but false for {}
except without arg: true but false for {}
dup: true
select: true but false for {} # in 3.0: false
reject: true but false for {} # in 3.0: false
merge: true but false for {}
transform_values: true but false for {}
transform_keys: false
to_h: false
to_h without block: true
```
Script:
```ruby
def check(method, label = method, *args, &block)
ci1, ci2 = [{a: 1}, {}].map do |h|
h.compare_by_identity
h2 = h.send(method, &block)
h2.compare_by_identity?
end
s = "#{label}: #{ci1}"
s << " but #{ci2} for {}" if ci2 != ci1
puts s
end
check(:slice, 'slice with arg', :a)
check(:slice, 'slice without arg')
check(:except, 'except with arg', :a)
check(:except, 'except without arg')
%i[dup select reject merge transform_values transform_keys to_h].each do |method|
check(method) { |k, v| [k, v] }
end
check(:to_h, 'to_h without block')
```
It's probably clear that the result should always be consistent for empty hash or not.
I feel the flag should be conserved for all these examples, except `to_h {...}` which should create an array without comparison by identity (as it does currently).
----------------------------------------
Bug #17757: Hash#slice does not keep compare_by_identity on the results
https://bugs.ruby-lang.org/issues/17757#change-91139
* Author: kachick (Kenichi Kamiya)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin20]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
GH-PR: https://github.com/ruby/ruby/pull/4330
```console
$ ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin20]
```
```ruby
str1 = +'str'
str2 = +'str'
hash = {a: :a, b: :b, c: :c}.compare_by_identity
hash[str1] = 1
hash[str2] = 2
p hash.values_at(str1, str2) #=> [1, 2]
p hash.except.compare_by_identity? #=> true
p hash.slice.compare_by_identity? #=> false
p hash.except(str1, str2) #=> {:a=>:a, :b=>:b, :c=>:c}
p hash.slice(str1, str2) #=> {"str"=>2}
```
Is this an intentional behavior?
I would expect Hash#slice keeps compare_by_identity behaviors.
--
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>