tcl
Argomenti procedurali
Ricerca…
Osservazioni
Riferimenti: proc
Espansione di argomenti (sezione 5)
Una procedura che non accetta argomenti
proc myproc {} {
puts "hi"
}
myproc
# => hi
Un elenco di argomenti vuoto (il secondo argomento dopo il nome della procedura, "mioproc") indica che la procedura non accetta argomenti.
Una procedura che accetta due argomenti
proc myproc {alpha beta} {
...
set foo $alpha
set beta $bar ;# note: possibly useless invocation
}
myproc 12 34 ;# alpha will be 12, beta will be 34
Se la lista degli argomenti è composta da parole, quelle saranno i nomi delle variabili locali nella procedura e i loro valori iniziali saranno uguali ai valori degli argomenti sulla riga di comando. Gli argomenti vengono passati per valore e qualsiasi cosa accada ai valori delle variabili all'interno della procedura non influenzerà lo stato dei dati al di fuori della procedura.
Una procedura che accetta un numero variabile di argomenti
### Definition
proc myproc {alpha {beta {}} {gamma green}} {
puts [list $alpha $beta $gamma]
}
### Use
myproc A
# => A {} green
myproc A B
# => A B green
myproc A B C
# => A B C
Questa procedura accetta uno, due o tre argomenti: quei parametri i cui nomi sono il primo elemento in un elenco di due elementi sono facoltativi. Le variabili di parametro ( alpha , beta , gamma ) ottengono tanti valori di argomento disponibili, assegnati da sinistra a destra. Le variabili di parametro che non ottengono alcun valore di argomento ottengono invece i loro valori dal secondo elemento nell'elenco di cui facevano parte.
Si noti che gli argomenti facoltativi devono arrivare alla fine dell'elenco degli argomenti. Se l'argomento N-1 è facoltativo, l'argomento N deve essere anch'esso facoltativo. Se in un caso, dove l'utente ha argomento N ma non argomento N-1 , il valore predefinito dell'argomento N-1 deve essere esplicitamente menzionato prima dell'argomento N , mentre si chiama la procedura.
myproc A B C D
# (ERROR) wrong # args: should be "myproc alpha ?beta? ?gamma?"
La procedura non accetta più di tre argomenti: si noti che viene creato automaticamente un utile messaggio di errore che descrive la sintassi degli argomenti.
Una procedura che accetta qualsiasi numero di argomenti
proc myproc args { ... }
proc myproc {args} { ... } ;# equivalent
Se il nome del parametro speciale args è l'ultimo elemento nell'elenco degli argomenti, riceve un elenco di tutti gli argomenti in quel punto nella riga di comando. Se non ce ne sono, l'elenco è vuoto.
Ci possono essere argomenti, compresi quelli opzionali, prima di args :
proc myproc {alpha {beta {}} args} { ... }
Questa procedura accetterà uno o più argomenti. I primi due, se presenti, saranno consumati da alpha e beta : l'elenco del resto degli argomenti verrà assegnato agli args .
Una procedura che accetta un nome / riferimento a una variabile
proc myproc {varName alpha beta} {
upvar 1 $varName var
set var [expr {$var * $alpha + $beta}]
}
set foo 1
myproc foo 10 5
puts $foo
# => 15
In questo caso particolare, alla procedura viene assegnato il nome di una variabile nell'ambito corrente. All'interno di una procedura Tcl, tali variabili non sono automaticamente visibili, ma il comando upvar può creare un alias per una variabile da un altro livello di stack: 1 indica il livello di stack del chiamante, # 0 indica il livello globale, ecc. In questo caso, il stack livello 1 e il nome foo (dalla variabile parametro varName ) consente a upvar trovare quella variabile e creare un alias chiamato var . Ogni operazione di lettura o scrittura su var avviene anche a foo nel livello di stack del chiamante.
La sintassi {*}
A volte quello che hai è un elenco, ma il comando che vuoi passare agli elementi nell'elenco richiede di ottenere ogni elemento come argomento separato. Ad esempio: il comando winfo children restituisce un elenco di finestre, ma il comando destroy richiede solo una sequenza di argomenti nome finestra.
set alpha [winfo children .]
# => .a .b .c
destroy $alpha
# (no response, no windows are destroyed)
La soluzione è usare la sintassi {*} :
destroy {*}[winfo children .]
o
destroy {*}$alpha
Ciò che la sintassi {*} fa è prendere il seguente valore (senza spazi vuoti in mezzo!) E unire gli elementi in quel valore nella linea di comando come se fossero argomenti individuali.
Se il seguente valore è una lista vuota, non viene inserito nulla:
puts [list a b {*}{} c d]
# => a b c d
Se ci sono uno o più elementi, vengono inseriti:
puts [list a b {*}{1 2 3} c d]
# => a b 1 2 3 c d