Возможна ли автоматическая инициализация многомерного хеш-массива в Ruby, как в PHP? - PullRequest
5 голосов
/ 30 июня 2010

Я так привык работать в PHP с многомерными массивами, где я могу назначить и инициализировать хэш с помощью

unset($a); // just to show that there is no variable $a
$a['settings']['system']['memory'] = '1 Gb';
$a['settings']['system']['disk space'] = '100 Gb';

Есть ли способ сделать подобное в Ruby?Или мне нужно сначала инициализировать все измерения, а затем назначить значения.Можно ли определить расширенный хэш, который позволит делать то, что мне нужно?Как бы вы это сделали?


Обновление

Помимо решения, предложенного Дугласом (см. Ниже), я обнаружил нить насубъект , в котором Брайан Шреаер предложил расширение для класса Hash:

class AutoHash < Hash
  def initialize(*args)
    super()
    @update, @update_index = args[0][:update], args[0][:update_key] unless args.empty?
  end

  def [](k)
    if self.has_key?k
      super(k)
    else
      AutoHash.new(:update => self, :update_key => k)
    end
  end

  def []=(k, v)
    @update[@update_index] = self if @update and @update_index
    super
  end
end

Это позволяет решить проблему, когда недостающий хеш-элемент нежелательно создается, когда значение элемента было толькозапрошено, например: a['key'].


Некоторые дополнительные ссылки

  1. Автовификация рубинового хэша (фасеты)
  2. http://trevoke.net/blog/2009/11/06/auto-vivifying-hashes-in-ruby/
  3. http://www.eecs.harvard.edu/~cduan/technical/ruby/ycombinator.shtml

1 Ответ

7 голосов
/ 30 июня 2010

Попробуйте это:

def hash_with_default_hash
    Hash.new { |hash, key| hash[key] = hash_with_default_hash }
end

a = hash_with_default_hash

Если ключ не существует, то результат блока будет использоваться в качестве значения по умолчанию. В этом случае значением по умолчанию также является хеш, который использует хеши в качестве значений по умолчанию.

...