Come abbiamo visto in un precedente articolo, nel paragrafo Come passare un array associativo ad una procedura, gli array in Tcl possono essere utilizzati anche come raccolte di variabili oltre che di valori.

Questo particolare utilizzo dell’array associativo ne limita però l’uso in alcuni casi, per esempio:

  • non possiamo passare un array associativo di variabili per valore ad una procedura;
  • non possiamo includerlo in altre strutture dati come per esempio una lista;
  • non possiamo gestirlo come array multidimensionale, ma dobbiamo sempre limitarci alla coppia nome/valore;
  • non possiamo inviarlo, così com’è, in un canale di comunicazione, ma dobbiamo prima trasformarlo in una singola stringa.

Per risolvere tutti questi inconvenienti, il nostro amico Tcl ci mette a disposizione un’altra struttura dati: il dizionario.

Caratteristiche di un dizionario

La struttura di un dizionario prevede una collezione di coppie chiave (key) e valore associato,

A differenza di un array che può essere utilizzato anche come collezione di variabili, un dizionario è concepito per raccoglie esclusivamente valori. Questo permette di passarlo ad una procedura come si fa per le stringhe o le liste.

Possiamo anche combinare il dizionario con altre strutture dati: per esempio potremmo avere una lista di dizionari che a loro volta contengono delle liste.

Il dizionario come base di dati gerarchica

Nonostante il dizionario sia una collezione di semplici coppie chiave/valore, in Tcl è possibile creare un dizionario che contenga a sua volta uno o più dizionari, ciascuno dei quali potrebbe contenere uno o più dizionari, e così via.

Questa particolarità ci permette di creare facilmente una vera e propria base dati gerarchica che possiamo rappresentare come un albero rovesciato dove ogni nodo può avere un solo padre e più figli.

Come creare un dizionario

Per creare un dizionario dobbiamo utilizzare il comando dict set.

# sintassi
dict set dictName key1 ?key2? ... ?keyn? myValue

Osservando con attenzione la sintassi del comando dict set, ci appare evidente come questo comando accetta una lista dove possiamo inserire un numero arbitrario di chiavi che vanno a formare una sorta di percorso lungo un ramo della nostra base dati gerarchica. Questo percorso conduce al valore vero e proprio che è l’ultimo elemento della lista.

In Tcl ogni dizionario è quindi anche una lista.

#
# Create a dictionary:
# Two clients, known by their client number,
# with forenames, surname
#
dict set clients ID1 forenames Joe
dict set clients ID1 surname   Schmoe
dict set clients ID2 forenames Anne
dict set clients ID2 surname   Other

In questa prima parte dell’esempio, il dizionario clients ha una sequenza di due chiavi per identificare correttamente un valore.

Come lavorare con i valori di un dizionario

#
# Print a table
#
puts "Number of clients: [dict size $clients]"
dict for {id info} $clients {
    puts "Client $id:"
    dict with info {
       puts "   Name: $forenames $surname"
    }
}
--
Number of clients: 2
Client ID1:
   Name: Joe Schmoe
Client ID2:
   Name: Anne Other

In questa seconda parte dell’esempio abbiamo un dizionario che ha due chiavi ID1 e ID2 di primo livello, ciascuna di queste chiavi rimanda ad un altro dizionario che, a sua volta, ha due chiavi di secondo livello forenames e surnames; infine ciascuna di queste chiavi è associata ad uno specifico valore.

Nonostante, come abbiamo visto, potremmo creare un numero arbitrario di chiavi ed avere quindi una struttura ad albero rovesciato la cui chioma diventa sempre più ampia, per la maggior parte dei problemi è molto spesso sufficiente una semplice struttura piatta singola-chiave/valore.

In relazione al comando dict for occorre evidenziare che questo ciclo scorre soltanto le chiavi del primo livello, quello più esterno.

Infine il comando dict with utilizza i nomi delle chiavi per creare delle variabili locali a cui poi assegna i valori associati nel dizionario.

Attenzione! Se il nostro programma fa delle variazioni in una o più di queste variabili locali, Tcl si occupa poi in automatico di aggiornare i valori anche sul dizionario originale.


Nel prossimo articolo vedremo come lavorare con i files.