« Tcl: Espressioni matematicheAppunti di Tcl/TkTcl: Controllo del flusso: comando switch »

Tcl

Controllo del flusso

comando if

La possibilità di scegliere tra due diramazioni del flusso dell'esecuzione di un programma basata sulla valutazione di una certa condizione booleana è fondamentale per poter codificare algoritmi in qualsiasi linguaggio di programmazione. Anche Tcl quindi ha un comando analogo all'istruzione if del linguaggio C, il comando if(n).

La sintassi generale di if(n) come indicato nella manpage è:

if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?

Gli argomenti then e else sono opzionali, alcuni preferiscono includerli perché ritengono che aumentino la leggibilità, altri invece li omettono in favore della brevità. Se bodyN manca, l'else che lo precede pure deve essere omesso. Le clausole elseif possono essere zero, una o più.

La semantica del comando if descritta a parole è la seguente: il valore di expr1 viene valutato tramite il comando expr(n). Il risultato di questa espressione deve essere booleano: le stringhe 0, false, no stanno per il valore logico falso; le stringhe 1, true, yes, o altri valori numerici diversi da 0, indicano il valore logico vero. La tabella seguente riassume come il comando if interpreta logicamente il risultato della valutazione delle sue espressioni. Notiamo che l'interpretazione delle stringhe yes,true e no,false è case insensitive:

Falso Vero
un valore numerico 0 tutti gli altri
yes/no no yes
true/false false true

Se una espressione ritorna qualcosa di diverso dai casi indicati nella tabella (ad es. la stringa "pippo") è un errore.

Se expr1 è vera, il comando if(n) farà eseguire lo script body1, passandolo all'interprete Tcl. Altrimenti, se expr2 è presente, viene valutata expr2 e se questa è vera viene eseguito body2, ecc. Se nessuna delle espressioni precedenti si valuta a true e bodyN è presente, allora viene eseguita bodyN.

Il valore di ritorno del comando if(n) sarà quello dello script body che è stato eseguito, oppure, nel caso nessuna delle espressioni era vera e non è presente la clausola else seguita da bodyN, la stringa vuota.

Occorre tenere presente che il test nel comando if viene eseguito tramite expr, senza che lo dobbiate dire esplicitamente ogni volta, ad esempio scrivendo al posto di expr1, [expr expr1]. Questo spiega ad esempio la differenza tra quotare il test tramite "" o {} o non quotarlo affatto. Nel caso di quotatura tramite i doppi apici o assenza di quotatura, vengono effettuate due fasi di sostituzione: una prima fase viene effettuata dal parser dell'interprete Tcl e un'altra viene effettuata dal comando expr(n) che if(n) internamente richiama. Nel caso di quotatura del test tramite {} invece viene effettuata una sola fase di sostituzione, che è quella fatta dal comando expr(n). Naturalmente è necessario quotare il test se questo non consiste di una sola parola, in quanto deve essere un argomento singolo di if(n).

Anche il body dovrà essere quotato se non costituito da una sola parola. Se viene quotato tramite { } allora avviene una sola fase di sostituzione nel momento in cui questo viene passato ad una istanza ricorsiva dell'interprete per essere eseguito. Se invece viene quotato tramite "" allora le fasi di sostituzione sono due: una effettuata dall'interprete che sta eseguendo l'istruzione if(n) e l'altra, che agirà sul risultato della prima, effettuata dall'interprete figlio che eseguirà il corpo selezionato. Da notare che la quote di apertura " o la parentesi graffa aperta devono trovarsi sulla stessa linea del comando if.

Sia per la condizione che per il body tipicamente non si richiede più di una fase di sostituzione e vengono utilizzate le parentesi graffe se necessarie; alcuni programmatori preferiscono usarle sempre per evitare problemi. Bisogna solo ricordarsi che in tal caso la sostituzione avviene anche attraverso le parentesi graffe, in quanto avviene nell'interprete figlio.

Ecco un esempio che dice se un numero x è pari o dispari:

if $x%2 {puts dispari} else {puts pari}
quotando la condizione con {} funziona ancora correttamente:
if {$x%2} {puts dispari} else {puts pari}
il quoting è necessario se si inseriscono degli spazi tra operando e operatore nella condizione:
% if $x % 2 {puts dispari} else {puts pari}
wrong # args: extra words after "else" clause in "if" command
su più linee possiamo scrivere:
if {$x % 2} {
  puts dispari
} else {
  puts pari
}

« Tcl: Espressioni matematicheAppunti di Tcl/TkTcl: Controllo del flusso: comando switch »