« Tcl: Iterazioni: comandi continue e break • Appunti di Tcl/Tk • Tcl: Creazione di nuovi comandi: comandi proc e return »
In Tcl puro non esiste l'equivalente dell'istruzione do ... while del C. Tuttavia data la natura estendibile di Tcl, è possibile implementarsela! Tcl è uno dei pochi linguaggi che permette di implementare nuove strutture di controllo in modo semplice. Questo è dovuto al fatto che in Tcl ci sono solo comandi, quindi anche le strutture di controllo sono dei comandi, ovvero possono essere definite come comandi o procedure, con l'aiuto di qualche altro comando specializzato.
Per esemplificare riportiamo di seguito l'implementazione di un comando do con la seguente semplice sintassi, simile a quella di while(n):
while body test
#!/bin/sh # restart using tclsh \ exec tclsh8.4 "$0" "$@" proc do {body test} { set code [catch {uplevel 1 $body} string] switch $code { 0 { # TCL_OK } 1 - 2 { # TCL_ERROR, TCL_RETURN return -code $code $string } 3 { # TCL_BREAK return } 4 { # TCL_CONTINUE } } uplevel [list while $test $body] }
Ecco uno spezzone di codice di test, che permette di giocare ad "indovina-un-numero":
# test: # the guess-a-number game set num [expr int(1+rand()*10)] set tries 0 puts {Guess a number between [1-10].} do { incr tries puts -nonewline "try #$tries: " flush stdout if {[gets stdin line]==-1 || [scan $line %d guess]!=1} { break } if {$guess==$num} { puts "You won with $tries tries." exit } } {$tries<5} puts "Game over. Number was $num."
Alcune osservazioni sull'implementazione di do:
while $test $bodyche implementa per noi le eventuali successive iterazioni. Questo corrisponde alla semantica del do...while del C.
uplevel 1 $bodymentre non occorre specificarlo nel comando uplevel successivo in quanto il primo argomento è la stringa costante while che non inizia per cifra o per #.
valore | codice | significato | significato della stringa |
---|---|---|---|
0 | TCL_OK | Il comando ha completato normalmente l'esecuzione | Risultato del comando |
1 | TCL_ERROR | Durante l'esecuzione del comando si è verificato un errore | Messaggio di errore |
2 | TCL_RETURN | Il comando ha richiesto che la procedura chiamante termini prematuramente, ritornando a sua volta lo stesso risultato del comando | Risultato del comando |
3 | TCL_BREAK | Il comand ha richiesto che il ciclo più interno in cui si trova termini | Stringa vuota |
4 | TCL_CONTINUE | Il comando ha richiesto che il cilo più interno in cui si trova salti alla prossima iterazione | Stringa vuota |
Il package control di Tcllib (una collezione di moduli di utilità per Tcl) fornisce un comando do ancora più flessibile, in quanto è possibile scegliere se la condizione deve essere una condizione di continuazione (semantica tipo while) o di terminazione del ciclo (semantica tipo until). Per usarlo basta caricare il package e utilizzare il nome pienamente qualificato del comando o importarlo nel namespace corrente:
package require control control::do { # corpo del ciclo # ... } while {test di continuazione} namespace import ::control::* do { # corpo del ciclo # ... } until {test di terminazione}
Vedere inoltre la manpage control(n), sezione LIMITATIONS, per una descrizione di una sottile limitazione legata alla gestione degli errori, di cui soffrono purtroppo tutti i comandi che implementano nuove strutture di controllo direttamente in Tcl, senza far ricorso ad estensioni scritte in C.
« Tcl: Iterazioni: comandi continue e break • Appunti di Tcl/Tk • Tcl: Creazione di nuovi comandi: comandi proc e return »