Hash хранит пары «ключ — значение», предоставляет быстрый доступ по ключу и сохраняет порядок вставки. Он удобен для настроек, счётчиков и данных с именованными полями. Ключи сравниваются с учётом hash и eql?, поэтому строка и одноимённый символ — разные ключи. Методы fetch и key? помогают отличать отсутствие ключа от сохранённых nil или false.
Чем хорош хеш в Ruby?
Доступ по ключу, порядок вставки и удобные операции Hash. Разница между отсутствующим ключом, nil и false.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Hash — ассоциативная коллекция. Вместо числового индекса можно обращаться к данным по смысловому ключу: имени настройки, идентификатору или символу. Типичные операции поиска и вставки в хеш-таблице имеют ожидаемую сложность O(1), но это не безусловная гарантия для любых ключей и коллизий.
user = { name: "Anna", roles: ["editor"], active: false }
user[:city] = "Kazan"
puts user[:name] # Anna
p user.fetch(:active, true) # false
p user.fetch(:timezone, "UTC") # "UTC"
p user.key?(:timezone) # false
p user["name"] # nil: ключ :name — не строка
Hash сохраняет порядок добавления ключей, что удобно при последовательном обходе. Методы each, keys, values, merge и delete позволяют работать со структурой без ручного поиска по массиву пар. Семантика Hash.
Для значения по умолчанию важно выбрать правильную операцию. Выражение options[:active] || true заменит не только отсутствие значения, но и явно переданный false; fetch(:active, true) сохраняет такой флаг. Если значение обязательно, fetch(:name) без значения по умолчанию сообщает об отсутствии ключа исключением.
У изменяемых объектов-ключей есть оговорка: изменение данных, влияющих на hash и eql?, может нарушить последующий поиск. Поэтому ключи лучше делать стабильными. И ещё одна ловушка: Hash.new([]) даёт один общий массив по умолчанию, а не отдельный для каждого ключа. Для группировки подходит Hash.new { |h, key| h[key] = [] }. Хеш удобен для гибкой структуры, но для сущности с обязательными полями и поведением иногда яснее отдельный класс.