« Tcl: Controllo del flusso: comando ifAppunti di Tcl/TkTcl: Iterazioni: comando while »

Tcl

Controllo del flusso

comando switch

switch(n) è un'altro comando che permette di scegliere una certa porzione di codice da eseguire tra un certo numero di porzioni di codice alternative. Tuttavia la scelta non si può basare su condizioni stabilite arbitrariamente, ma si limita a confrontare una stringa con un insieme di modelli o pattern, ciascuno associato ad una sezione di codice. Se la stringa corrispone al pattern viene eseguita la porzione di codice associata.

La sintassi di switch(n) può essere di due tipi:

switch ?options? string pattern1 body1 ?pattern2 body2? ... ?patternN bodyN?

switch ?options? string {pattern1 body1 ?pattern2 body2? ... ?patternN bodyN?}

string è la stringa che verrà confrontata con i pattern pattern1 ... patternN, in questo ordine. I confronti vengono arrestati quando si trova un pattern, poniamo patternI (1<=I && I<=N) che corrisponde alla stringa string. In tal caso verrà eseguito il codice bodyI e il suo valore di ritorno costituirà il valore ritornato dal comando switch(n). I pattern con indici patternI+1 ... patternN non verranno proprio controllati, ossia il comando switch(n) termina con l'esecuzione di bodyI e l'interprete Tcl prosegue con l'esecuzione del comando successivo allo switch(n).

Se non si trova nessun pattern che corrisponde alla stringa, dopo che tutti i pattern sono stati analizzati, il comando switch termina restituendo la stringa nulla. Questo può essere cambiato inserendo come ultimo pattern la stringa speciale default. Il pattern default fa corrispondenza con qualsiasi stringa e la sua semantica è quindi analoga a quella della clausola else del comando if(n). Quindi se il pattern default è presente, il corpo corrispondente verrà certamente eseguito nel caso string non faccia corrispondenza con qualsiasi altro pattern e può ritornare qualcosa di diverso dalla stringa nulla. Se invece non c'è un pattern di default, restando sempre nell'ipotesi che nessuno degli altri pattern ha fatto corrispondenza con la stringa, il comando switch termina restituendo la stringa nulla.

Col comando switch(n) un solo pattern può fare corrispondenza, oppure nessuno.

switch(n) è un costrutto di selezione meno generale di if(n); ciascuno switch(n) può essere espresso tramite un if(n) corrispondente, mentre il viceversa non è vero. switch(n) esiste solo perchè risulta maggiormente leggibile rispetto all'if(n) corrispondente.

Nella prima sintassi del comando ciascun pattern e ciascun body vengono passati come argomenti separati. Nella seconda forma invece vengono tutti raggruppati in un argomento singolo racchiuso tra parentesi graffe, lasciando che sia switch(n) a fare il lavoro di separare i vari pattern e i body. In quest'ultimo caso viene evitato ogni tipo di sostituzione di variabile sui pattern.

Inoltre se un corpo viene racchiuso tra { }, switch(n) (come if(n)) elimina le { } prima di passare all'interprete Tcl il body per la sua valutazione. In questo modo l'interprete figlio effettua la fase di sostituzione sul body che viene eseguito, anche se questo era racchiuso tra { }.

Le { } sono comode perché permettono di scrivere più comandi in modo più leggibile, distribuendoli su varie linee e senza dover usare il backslash alla fine di ogni linea.

Questo esempio stampa il nome in inglese della cifra contenuta nella variabile x:

switch $x 0 {puts zero} 1 {puts one} 2 {puts two} 3 {puts three} 4 {puts four} 5 {puts five} 6 {puts six} 7 {puts seven} 8 {puts eight} 9 {puts nine}

Qui le parentesi graffe sono necessarie perché ogni corpo deve essere un unico parametro. Per ragioni di leggibilità possiamo dividerlo in vari modi su più linee. Eccone mostrati alcuni. Il secondo di questi esempi introduce anche il caso di default:

switch $x 0 {puts zero} 1 {puts one} 2 {puts two} 3 {puts three} \
4 {puts four} 5 {puts five} 6 {puts six} 7 {puts seven} \
8 {puts eight} 9 {puts nine}
switch $x \
  0 "puts zero" \
  1 "puts one" \
  2 "puts two" \
  3 "puts three" \
  4 "puts four" \
  5 "puts five" \
  6 "puts six" \
  7 "puts seven" \
  8 "puts eight" \
  9 "puts nine" \
  default "puts {error: not a digit}"
switch $x {
  0 {puts zero}
  1 {puts one}
  2 {puts two}
  3 {puts three}
  4 {puts four}
  5 {puts five}
  6 {puts six}
  7 {puts seven}
  8 {puts eight}
  9 {puts nine}
}
switch $x 0 {
  puts zero
} 1 {
  puts one
} 2 {
  puts two
} 3 {
  puts three
} 4 {
  puts four
} 5 {
  puts five
} 6 {
  puts six
} 7 {
  puts seven
} 8 {
  puts eight
} 9 {
  puts nine
}

Il concetto di corrispondenza per default significa uguaglianza tra la stringa string e il pattern, ma le opzioni permettono di complicare il significato di corrispondenza facendo interpretare il pattern come un descrittore di un particolare linguaggio regolare (espressione regolare). Vedere switch(n) e la sezione sulle espressioni regolari per approfondire.

« Tcl: Controllo del flusso: comando ifAppunti di Tcl/TkTcl: Iterazioni: comando while »