хэш-функции по умолчанию не делает работайте так, как вы ожидаете. Когда вы говорите h[k]
, процесс выглядит следующим образом:
- Если у нас есть
k
ключа, возвращает его значение.
- Если у нас есть значение по умолчанию для Hash, верните это значение по умолчанию.
- Если у нас есть блок для предоставления значений по умолчанию, выполните блок и верните его возвращаемое значение.
Обратите внимание, что (2) и (3) ничего не говорят о вставке k
в хэш. Значение по умолчанию, по существу превращает h[k]
в этом:
h.has_key?(k) ? h[k] : the_default_value
Так просто доступ к несуществующему ключу и получить значение по умолчанию обратно не добавят недостающий ключ к Hash.
Кроме того, все формы:
Hash.new([ ... ])
# or
Hash.new({ ... })
почти всегда ошибка, как вы будете делить точно такой же массив по умолчанию или хэша для всех значений по умолчанию. Например, если вы сделаете это:
h = Hash.new(['a'])
h[:k].push('b')
Тогда h[:i]
, h[:j]
... все будет возвращаться ['a', 'b']
и это редко, что вы хотите.
Я думаю, что вы ищете block form of the default value:
h = Hash.new { |h, k| h[k] = [ 'alright' ] }
Это будет делать две вещи:
- Доступ к несуществующий ключ будет добавить, что ключ к Hash и она будет иметь предоставленный массив в качестве значения.
- Все значения по умолчанию будут различными объектами, поэтому их изменение не изменит остальных.
Законный вопрос, но это, вероятно, дубликат. –