2010-06-30 7 views
5

Estoy tan acostumbrado a trabajar en PHP con matrices multidimensionales, donde puede asignar e inicializar un hash por¿Es posible la inicialización automática de matrices hash multidimensionales en Ruby, como en 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'; 

¿Hay una manera de hacer algo similar en Ruby? O primero necesito inicializar todas las dimensiones y luego asignar valores. ¿Es posible definir un Hash avanzado que permita hacer lo que necesito? ¿Cómo lo harías tú?


actualización

Además de la solución propuesta por Douglas (ver más abajo), he encontrado un thread on the subject, en el que Brian Schröäer ha propuesto una extensión para la clase 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 

Permite resolver el problema cuando un elemento hash faltante se crea indeseablemente cuando el valor del elemento solo se solicitó, por ejemplo a['key'].


Algunas referencias adicionales

  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

Soy un hombre PHP y sé poco sobre Ruby, pero en mi opinión, este es uno de los rasgos horribles de PHP que no debería exportarse a otros idiomas. :) (Aunque entiendo por qué uno lo querría en tal situación.) –

Respuesta

7

Prueba esto:

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

a = hash_with_default_hash 

Si la clave no existe, el resultado del bloque se utilizará como valor predeterminado. En este caso, el valor predeterminado es también un hash que usa hashes como sus valores predeterminados.

+1

¡Funciona como un encanto! Gracias, Douglas – Andrei

+0

. Hay una cosa más que desear: si solo compruebo el valor del elemento 'a ['key']', se creará un nuevo elemento con la tecla 'clave' en caso de que no exista. ¿Cómo se puede evitar tal comportamiento? – Andrei

+1

¿Estás buscando Hash # has_key? http://ruby-doc.org/core/classes/Hash.html#M002883 – Douglas

Cuestiones relacionadas