В ОП я сказал, что у меня свое мнение. Вот оно.
Хотя подход «причудливый инициализатор» элегантен, он может привести к некоторому действительно неожиданному поведению - особенно к генерации ключей, когда вы этого не ожидаете - и нет способа узнать это, посмотрев на хеш-таблицу.
Рассмотрим следующее:
>> ht1 = Hash.new {|h,k| h[k]=[]}
>> ht2 = {}
>> ht1["cats"] << "Jellicle"
=> ["Jellicle"]
>> (ht2["cats"] ||= []) << "Jellicle"
=> ["Jellicle"]
пока все хорошо - ht1 и ht2 идентичны. но:
>> ht1["dogs"] ? "got dogs" : "no dogs"
=> "got dogs"
>> ht2["dogs"] ? "got dogs" : "no dogs"
=> "no dogs"
Обратите внимание, что простой доступ к ht1 [some_key] изменяет состояние хеш-таблицы , т. Е. Создает новую запись. Вы можете утверждать, что конечный пользователь всегда должен использовать has_key? () Для проверки наличия хеш-записи - и вы были бы правы - но приведенное выше использование является принятой идиомой. Автоматическое создание записи в хеш-таблице было бы неожиданным побочным эффектом, поэтому следует соблюдать осторожность, если хеш-таблица когда-либо будет доступна конечному пользователю. (Обратите внимание, однако, что ответ Стинслага показывает, как вы можете отключить это.)