tcl
Procedure-argumenten
Zoeken…
Opmerkingen
Referenties: proc
Argumentuitbreiding (paragraaf 5)
Een procedure die geen argumenten accepteert
proc myproc {} {
puts "hi"
}
myproc
# => hi
Een lege lijst met argumenten (het tweede argument na de procedurenaam, "myproc") betekent dat de procedure geen argumenten accepteert.
Een procedure die twee argumenten accepteert
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
Als de argumentlijst uit woorden bestaat, zijn dit de namen van lokale variabelen in de procedure en zijn hun beginwaarden gelijk aan de argumentwaarden op de opdrachtregel. De argumenten worden doorgegeven door waarde en wat er ook gebeurt met de variabele waarden binnen de procedure heeft geen invloed op de status van gegevens buiten de procedure.
Een procedure die een variabel aantal argumenten accepteert
### 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
Deze procedure accepteert een, twee of drie argumenten: de parameters waarvan de namen het eerste item in een lijst met twee items zijn, zijn optioneel. De parametervariabelen ( alpha , beta , gamma ) krijgen zoveel argumentwaarden als beschikbaar, van links naar rechts toegewezen. Parametervariabelen die geen argumentwaarden krijgen, halen hun waarden in plaats daarvan uit het tweede item in de lijst waarvan ze deel uitmaken.
Merk op dat optionele argumenten aan het einde van de lijst met argumenten moeten komen. Als argument N-1 optioneel is, moet argument N ook optioneel zijn. Als in een geval, waarbij de gebruiker argument N heeft maar niet argument N-1 , de standaardwaarde van argument N-1 expliciet moet worden vermeld vóór argument N , terwijl de procedure wordt aangeroepen.
myproc A B C D
# (ERROR) wrong # args: should be "myproc alpha ?beta? ?gamma?"
De procedure accepteert niet meer dan drie argumenten: merk op dat er automatisch een nuttig foutbericht wordt gemaakt dat de syntaxis van het argument beschrijft.
Een procedure die een willekeurig aantal argumenten accepteert
proc myproc args { ... }
proc myproc {args} { ... } ;# equivalent
Als de speciale parameternaam args het laatste item in de lijst met argumenten is, ontvangt deze een lijst met alle argumenten op dat punt in de opdrachtregel. Als er geen zijn, is de lijst leeg.
Er kunnen argumenten, inclusief optionele, vóór args :
proc myproc {alpha {beta {}} args} { ... }
Deze procedure accepteert een of meer argumenten. De eerste twee, indien aanwezig, worden gebruikt door alpha en beta : de lijst met de overige argumenten wordt toegewezen aan args .
Een procedure die een naam / verwijzing naar een variabele accepteert
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 dit specifieke geval krijgt de procedure de naam van een variabele in het huidige bereik. Binnen een Tcl-procedure zijn dergelijke variabelen niet automatisch zichtbaar, maar de opdracht upvar kan een alias maken voor een variabele van een ander upvar : 1 betekent het upvar de beller, # 0 betekent het globale niveau, enz. In dit geval stapel niveau 1 en de naam foo (van de parameter variabele varName ) laat upvar die variabele vinden en een alias maken met de naam var . Elke lees- of schrijfbewerking op var gebeurt ook met foo in het foo van de beller.
De syntaxis {*}
Soms heb je een lijst, maar de opdracht waaraan je de items in de lijst wilt doorgeven vereist dat elk item als een afzonderlijk argument wordt opgehaald. Bijvoorbeeld: de opdracht winfo children retourneert een lijst met vensters, maar de opdracht destroy heeft alleen een reeks vensternaamargumenten nodig.
set alpha [winfo children .]
# => .a .b .c
destroy $alpha
# (no response, no windows are destroyed)
De oplossing is om de syntaxis {*} te gebruiken:
destroy {*}[winfo children .]
of
destroy {*}$alpha
Wat de syntaxis {*} doet, is de volgende waarde te nemen (geen witruimte ertussen!) En de items in die waarde in de opdrachtregel te splitsen alsof het afzonderlijke argumenten waren.
Als de volgende waarde een lege lijst is, wordt er niets ingesplitst:
puts [list a b {*}{} c d]
# => a b c d
Als er een of meer items zijn, worden deze ingevoegd:
puts [list a b {*}{1 2 3} c d]
# => a b 1 2 3 c d