Project

General

Profile

Actions

Bug #20880

closed

Hash allows array-type key duplicates

Added by alexfrstnberg (Yana Prystopchuk) 14 days ago. Updated 14 days ago.

Status:
Rejected
Assignee:
-
Target version:
-
ruby -v:
ruby 3.3.5 (2024-09-03 revision ef084cc8f4) [arm64-darwin23]
[ruby-core:119822]

Description

I was solving small tasks on Leetcode and encountered an issue with Hash which looked strange to me:

There's an array saved into the variable and a hash with a previously created array as a key

arr = [1,2,3]
hsh = {arr => 1}
=> {[1, 2, 3]=>1}

Modified the array. Added the same array to the same hash.

arr << 4
hsh[arr] = 2
=> {[1, 2, 3, 4]=>1, [1, 2, 3, 4]=>2}

Added another duplicate

arr << 5
hsh[arr] = 3
=> {[1, 2, 3, 4, 5]=>1, [1, 2, 3, 4, 5]=>2, [1, 2, 3, 4, 5]=>3}

First issue:

As a user, I'd expect to have the already existing key reassigned with the new value. Since the key is duplicated, now it's not obvious which value 1, 2, or 3 should be returned for the key ([1, 2, 3, 4, 5] or arr).

Second issue:

When trying to actually retrieve a value, different methods behave differently:

hsh[[1,2,3,4,5]]
=> 3
hsh[arr]
=> 3

But

hsh.assoc(arr)
=> 1

Third issue:

Another example is created:

arr = [1]
hsh = {arr => 1}

And modified with the same logic using a loop:

incr = 1
10.times do
  arr << (incr += 1)
  hsh[arr] = incr
end

The received hsh:

=> 
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]=>9,
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]=>2,
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]=>3,
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]=>4,
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]=>5,
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]=>6,
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]=>7,
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]=>8,
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]=>10,
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]=>11}

As you can see, the first key eventually got reassigned (there's no value 1 anymore, it was replaced by 9)
I tried to add each next key manually and got the same result: 1 is replaced by 9.

Actions #1

Updated by alexfrstnberg (Yana Prystopchuk) 14 days ago

  • ruby -v changed from 3.3.5 to ruby 3.3.5 (2024-09-03 revision ef084cc8f4) [arm64-darwin23]

Updated by jeremyevans0 (Jeremy Evans) 14 days ago

  • Status changed from Open to Rejected

This is not a bug, it is expected. It's best not to mutate objects used as hash keys, but Ruby doesn't stop you from doing it. If you do mutate an object used as a hash key, you need to call rehash on the hash to update it (https://docs.ruby-lang.org/en/master/Hash.html#method-i-rehash):

arr = [1,2,3]
hsh = {arr => 1}
arr << 4
hsh.rehash
hsh[arr] = 2
hsh
# => {[1, 2, 3, 4]=>2}
Actions

Also available in: Atom PDF

Like0
Like0Like0