2010-06-30 18 views
5

Jestem tak przyzwyczajony do pracy w PHP z tablic wielowymiarowych, w którym można przypisać i zainicjować hash przezCzy możliwa jest inicjalizacja automatycznie wielowymiarowych tablic asocjacyjnych w Ruby, tak jak w 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'; 

Czy istnieje sposób, aby zrobić coś podobnego w Ruby? Lub muszę najpierw zainicjować wszystkie wymiary, a następnie przypisać wartości. Czy można zdefiniować zaawansowane Hash, które pozwoli robić to, czego potrzebuję? Jak byś to zrobił?


Aktualizacja

Oprócz rozwiązania zaproponowanego przez Douglas (patrz poniżej), znalazłem thread on the subject, w którym Brian Schröäer zaproponowała rozszerzenie dla klasy 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 

Pozwala to rozwiązać problem, gdy brakujący hasz został utworzony w sposób niepożądany, gdy żądano tylko wartości pozycji, np. a['key'].


Niektóre dodatkowe referencje

  1. ruby hash autovivification (facets)
  2. http://trevoke.net/blog/2009/11/06/auto-vivifying-hashes-in-ruby/
  3. http://www.eecs.harvard.edu/~cduan/technical/ruby/ycombinator.shtml
+0

Jestem człowiekiem PHP i niewiele wiem o Rubim, ale moim zdaniem jest to jedna z okropnych cech PHP, która nie powinna być eksportowana do innych języków. :) (Chociaż rozumiem, dlaczego ktoś by tego chciał w takiej sytuacji.) –

Odpowiedz

7

Spróbuj tego:

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

a = hash_with_default_hash 

Jeśli klucz nie istnieje, wynik bloku zostanie użyty jako wartość domyślna. W tym przypadku wartością domyślną jest również skrót, który używa wartości skrótów jako wartości domyślnych.

+1

Działa jak urok! Dziękuję, Douglas – Andrei

+0

Jest jeszcze jedna rzecz do życzenia - jeśli po prostu sprawdzę wartość pozycji 'a ['klucz']', to nowa pozycja z kluczem 'klucz' zostanie utworzona na wypadek, gdyby nie istniała. Jak można uniknąć takiego zachowania? – Andrei

+1

Masz za Hash # has_key? http://ruby-doc.org/core/classes/Hash.html#M002883 – Douglas

Powiązane problemy