Ответ 1
Ожидается поведение (во всех рубиновых версиях). И если вы немного экспериментируете, вы увидите, что вы всегда получаете доступ к одному и тому же хэшу, независимо от того, какой ключ вы используете:
>> a[:a][:b] = 1
=> 1
>> a[:c][:d] = 2
=> 2
>> a[:d]
=> {:b=>1, :d=>2}
Способ Hash.new с аргументом по умолчанию работает: Если вы выполняете hash[key]
, он проверяет, существует ли этот ключ в хэше. Если это так, оно возвращает значение для этого ключа. Если он не возвращает значение по умолчанию. Он не добавляет ключ к хешу, и он будет возвращать один и тот же объект по умолчанию (а не копию) каждый раз.
Чтобы получить то, что вы хотите, вы хотите вместо этого указать блок по умолчанию. Таким образом, блок будет выполняться каждый раз, когда вы получаете доступ к ключу, который не находится в хэше. Внутри блока вы можете создать новый хэш и установить ключ для "хэша". Например:
Hash.new { |h,k| h[k] = {} }