Рассмотрите этот код:
h = Hash.new(0) # New hash pairs will by default have 0 as values
h[1] += 1 #=> {1=>1}
h[2] += 2 #=> {2=>2}
Это - весь штраф, но:
h = Hash.new([]) # Empty array as default value
h[1] <<= 1 #=> {1=>[1]} ← Ok
h[2] <<= 2 #=> {1=>[1,2], 2=>[1,2]} ← Why did `1` change?
h[3] << 3 #=> {1=>[1,2,3], 2=>[1,2,3]} ← Where is `3`?
В этой точке я ожидаю, что хеш будет:
{1=>[1], 2=>[2], 3=>[3]}
но это далеко от этого. Что происходит и как я могу получить поведение, которое я ожидаю?
Вы указываете, что значение по умолчанию для хеша является ссылкой на этот конкретный (изначально пустой) массив.
Думаю, вы хотите:
h = Hash.new { |hash, key| hash[key] = []; }
h[1]<<=1
h[2]<<=2
Это устанавливает значение по умолчанию для каждого ключа в новый массив.