Hash Infinito

Vedi tutte le pagine e le modifiche recenti o scarica i sorgenti nella pagina


Cosa intendiamo per hash infinito ? Beh si tratta di un oggetto con cui si possa fare così;:
 >> superhash['primo']= "alore" 
 => "alore" 
 >> superhash['due']['livelli']
 => {}
 >> superhash['due']['livelli']= 'ciao'
 => "ciao" 
 >> superhash
 => {"primo"=>"alore", "due"=>{"livelli"=>"ciao"}}
 >> superhash[:tutti][:i]['livelli']['che']["desiderate"]= "bau" 
 => "bau" 
 >> superhash
 => {"primo"=>"alore","due"=>{"livelli"=>"ciao"},
      :tutti=>{:i=>{"livelli"=>{"che"=>{"desiderate"=>"bau"}}}}}

In pratica simula quello che in letteratura viene detto sparse Array multidimensionale’ cioe’ un Array in cui solo pochi degli elementi hanno un valore.

Ad esempio, pensate a dover gestire un cinema. Userete una matrice per i posti, quindi ogni posto sara’ sala[fila][seggiolino]. Ma sapete che il vostro film trasmette solo musical postrealisti del tagikistan, e nel vostro quartiere ci sono pochi cinefili, quindi avrete pochi utenti. Non conviene mantenere un’intera matrice. Ci bastera’ usare il nostro superhash.

Per crearlo farete cosi’;:
 >> hash_maker = proc do |h, k|
 ?>    h[k] = Hash.new(&hash_maker)
 >> end
 => #<Proc:0x027d1520@(irb):1>
 >> sala=Hash.new &hash_maker
 => {}
Ora potete assegnare i posti che volete:
 >> sala[0][1]='signor rossi'
 => "signor rossi" 
 >> sala[2][20]='signora bianchi'
 => "signora bianchi" 
 >> sala[5][12]='signor mori'
 => "signor mori" 
 >> sala.size
 => 3
Abbiamo usato solo lo spazio che ci serviva.

Ma spieghiamo il trucco:

Un Hash puo’ essere creato con un valore predefinito, che e’ il risultato di un blocco passato al costruttore new(). Possiamo fare questa cosa amnche con gli Array ed e’ molto utile perche’ ci permette di inizializzare questi oggetti quando li costruiamo, invece di usare due operazioni separate.

Poiche’ un Hash non ha dimensione fissata non possiamo calcolare a priori i valori come, cosa che avviene invece con Array.new block:
 >> x=0
 => 0
 >> ary=Array.new(10) { x+=1 }
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Dunque la procedura (nel nostro caso hash_maker) viene richiamata quando accediamo ad una chiave che non e’ gia stata creata. Ad esempio:
 >> hsh=Hash.new {|hash,kiave| hash[kiave]=x+=1  }
 => {}
 >> hsh[:a]
 => 11
 >> hsh[:s]
 => 12
 >> hsh[29]
 => 13
(spero sia chiaro che proseguiamo l’esempio di prima :P)

Nel nostro caso abbiamo usato una procedura, hash_maker che ogni volta crea un nuovo Hash con se stessa come valore di default, permettendo di aggiungere infiniti livelli. Fico vero?

Ah, se non lo sapeste, scrivere &oggetto_di_tipo_procedura serve a dire a ruby espandi questo blocco, come se avessi scritto do..end in questo punto

Updated on November 26, 2005 13:10 by Ruby Fan (151.37.150.7)