Appunti di Tcl/TkInstallazione in FreeBSD »

Introduzione

Tcl (Tool Command Language) è un linguaggio di scripting general purpose, estendibile, ad alto livello, multipiattaforma, open-source e incorporabile in altri linguaggi (C, C++ compresi) o applicazioni, simile al Perl o al linguaggio della C shell csh(1) (vi sono anche influenze del linguaggio C e del Lisp). Tcl si pronuncia come tickle. Fu ideato dal Professor John K. Ousterhout all'Università della California di Berkeley nel 1988. Tcl è un linguaggio interpretativo, ma può anche essere parzialmente compilato. L'interprete è disponibile per le tre piattaforme più diffuse (UNIX, Windows, Macintosh). Estensioni al linguaggio (nuovi comandi) possono essere scritte in C o in Tcl stesso e facilmente incorporate. Inoltre da uno script Tcl è possibile eseguire altri programmi esterni, come si fa negli script di shell UNIX.

Strettamente parlando Tcl non è un linguaggio di programmazione di sistema come C o derivati, in quanto manca di alcune funzionalità. Infatti non ha gli array, ma solo gli array associativi e non ha puntatori, quindi non è possibile creare strutture dati dinamiche come liste concatenate, o alberi con puntatori, e non è nemmeno un linguaggio orientato agli oggetti. Queste limitazioni possono essere facilmente superate incorporando Tcl in un altro linguaggio di sistema, oppure tramite opportune estensioni di Tcl che sono disponibili. Il linguaggio Incr Tcl è una estensione orientata agli oggetti di Tcl. I linguaggi Python e Perl sono dei competitori di Tcl e in verità sono per certi aspetti più potenti di Tcl, ma Tcl rimane il più semplice da usare ed imparare.

Questi appunti non hanno la pretesa di essere una guida definitiva su Tcl. Consiglio vivamente a chiunque voglia approfondire di leggere le pagine di manuale e i riferimenti consigliati Questo testo ha il solo scopo di presentare i concetti più importanti in una forma facilmente fruibile, per mettere in grado coloro che sono nuovi al linguaggio di programmare applicazioni utili in poco tempo.

Il seguente programma in Tcl è una versione leggermente modificata (per adattarla alle versioni moderne di Tcl/Tk) di un esempio proposto da Ousterhout in un articolo introduttivo su Tk. Si tratta un file browser e costituisce un semplice esempio di applicazione che illustra i pregi e la semplicità di Tcl come "linguaggio colla". Per provarlo salvatelo in file eseguibile di nome browse in una directory inclusa nel percorso di ricerca della shell (oppure assicuratevi che la directory corrente in cui si trova sia inclusa nel percorso e lanciatelo da lì):

#!/bin/sh
# \
exec wish8.4 "$0" "$@"

scrollbar .scroll -command ".list yview"
listbox .list -relief raised -width 20 -height 20 -yscrollcommand ".scroll set"
pack .scroll -side right -fill y
pack .list -side left -expand yes -fill both

proc browse {dir file} {
    if {[string compare $dir "."] != 0} {set file $dir/$file}
    if [file isdirectory $file] {
        set cmd [list exec sh -c "browse $file" &]
        eval $cmd
    } else {
        if [file isfile $file] {exec xedit $file &} else {
            puts "$file isn't a directory or regular file"
        }
    }
}

if $argc>0 {set dir [lindex $argv 0]} else {set dir "."}
wm title . browse:[file normalize $dir]
eval .list insert 0 [split [exec ls -aF $dir] \n]

bind .list <Double-Button-1> {foreach i [selection get] {browse $dir $i}}
bind . <Control-q> {destroy .}
esempio di browsing con browse

Non preoccupatevi per ora se questo programma vi sembra oscuro. Man mano che procederete nella lettura i dettagli saranno spiegati con calma. Per ora accontentatevi di una descrizione approssimativa e semplificata di cosa fa ciascun gruppo logico di istruzioni.

#!/bin/sh
# \
exec wish8.4 "$0" "$@"

Questi commenti indicano al sistema operativo di eseguire il programma tramite l'interprete Tcl/Tk.

scrollbar .scroll -command ".list yview"
listbox .list -relief raised -width 20 -height 20 -yscrollcommand ".scroll set"
pack .scroll -side right -fill y
pack .list -side left -expand yes -fill both

Questi comandi creano un controllo di scorrimento e uno di lista, affiancati nella finestra dell'applicazione. Lo scorrimento controlla la vista nella lista e viceversa quando si scorre la lista senza far uso della barra, anche la barra di scorrimento si muoverà come se se ne fosse fatto uso per ottenere lo stesso scorrimento.

proc browse {dir file} {
    if {[string compare $dir "."] != 0} {set file $dir/$file}
    if [file isdirectory $file] {
        set cmd [list exec sh -c "browse $file" &]
        eval $cmd
    } else {
        if [file isfile $file] {exec xedit $file &} else {
            puts "$file isn't a directory or regular file"
        }
    }
}

Il comando proc crea un nuovo comando o procedura chiamato browse, che ha due argomenti, dir e file, i quali insieme rappresentano un percorso. Con dir si intende il nome della variabile dir, mentre con $dir se ne intende il valore e analogamente per ogni altra variabile. Se dir è un ., il percorso specificato è il percorso $file, altrimenti si considera il percorso $dir/$file. Se il percorso così ottenuto rappresenta una directory verrà avviata una nuova versione del browser per visualizzare il contenuto della directory, come si vede in figura per la directory bin/; se invece il percorso rappresenta un file regolare, verrà avviato l'editor xedit(1) sul file. Se è qualcosa di diverso da una directory o un file regolare, ad esempio è un file speciale di dispositivo (ad es. /dev/fd0) o un file eseguibile (ad es. /bin/cp), viene stampato un messaggio di errore.

if $argc>0 {set dir [lindex $argv 0]} else {set dir "."}

Questo comando imposta la variabile globale dir che verrà passata come primo parametro attuale alla procedura browse (notate che anche il parametro formale si chiama dir, ma questo non causa alcun problema). La globale dir assumerà il valore del primo argomento sulla riga di comando di browser, o in mancanza di argomenti, verrà inizializzata con un . (che indica la directory corrente).

wm title . browse:[file normalize $dir]

Imposta il titolo col formato che vedete nella figura. $dir viene convertito in un path assoluto. Invece di usare il sottocomando [exec realpath $dir], è meglio usare il comando file normalize(n) che è più portabile. Infatti realpath(1) non funziona in alcune versioni di Unix che ne sono sprovviste.

eval .list insert 0 [split [exec ls -aF $dir] \n]

Inserisce nella listbox tutti i nomi dei file o di altri directory contenuti nella directory $dir, compresi quelli che iniziano col punto (opzione -a di ls). Nella versione originale questo veniva fatto file per file tramite il ciclo seguente:

foreach i [exec ls -aF $dir] {
    .list insert end $i
}

Questo codice tuttavia non gestisce correttamente quei nomi dei file che contengono degli spazi: ogni parola viene considerata erroneamente come un file separato.

bind .list <Double-Button-1> {foreach i [selection get] {browse $dir $i}}
bind . <Control-q> {destroy .}

Stabilisce come devono essere gestiti alcuni eventi dell'interfaccia grafica. Se si fa doppio click col tasto sinistro del mouse (identificato dal numero 1) su una voce della lista, verrà invocata la procedura browse definita prima per ciascun elemento della lista selezionato, usando gli argomenti $dir e $i dove $i è l'elemento selezionato. Se si preme Control-q invece si esce dall'applicazione.

A questo punto dovrebbe esservi chiaro come funziona il programma browser. Anche se non ne avete ancora una conoscenza approfondita, dovreste aver ricevuto l'impressione che Tcl è un linguaggio di altissimo livello, facile e molto espressivo e spero che questo vi fornisca un buon motivo per imparare Tcl e continuare con le pagine successive.

Appunti di Tcl/TkInstallazione in FreeBSD »