Проблема
Вызывая
map["a"].push("hello")
, вы изменяете объект Hash по умолчанию.Фактически, после этого каждый возможный ключ доставит «привет», но ключ на самом деле не инициализирован.Хеш будет знать только свой объект по умолчанию, но вы не сказали ему «инициализировать» ключ.
ruby-1.9.2-head :002 > map["a"].push("Hello")
=> ["Hello"]
ruby-1.9.2-head :003 > map["a"]
=> ["Hello"]
ruby-1.9.2-head :004 > map["b"]
=> ["Hello"]
ruby-1.9.2-head :004 > map.keys
=> []
Что вы можете сделать, это специально инициализировать ключ:
ruby-1.9.2-head :008 > map["a"] = Array.new
=> []
ruby-1.9.2-head :009 > map.keys
=> ["a"]
Но на самом деле это не то, что вам нужно.
Решение:
Такое поведение по умолчанию может быть достигнуто с помощью следующего метода для инициализации хэша:
map = Hash.new { |hash, key| hash[key] = Array.new }
Например:
ruby-1.9.2-head :010 > map = Hash.new { |hash, key| hash[key] = Array.new }
=> {}
ruby-1.9.2-head :011 > map["a"]
=> []
ruby-1.9.2-head :012 > map["b"]
=> []
ruby-1.9.2-head :013 > map.keys
=> ["a", "b"]
(я не специалист по Ruby, поэтому, если есть предложения, добавьте комментарий)