tcl
Procedurargument
Sök…
Anmärkningar
Referenser: proc
Utvidgning av argument (avsnitt 5)
Ett förfarande som inte accepterar argument
proc myproc {} {
puts "hi"
}
myproc
# => hi
En tom argumentlista (det andra argumentet efter procedurnamnet, "myproc") betyder att proceduren inte accepterar argument.
Ett förfarande som accepterar två argument
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
Om argumentlistan består av ord kommer dessa att vara namnen på lokala variabler i proceduren, och deras initiala värden kommer att vara lika med argumentvärdena på kommandoraden. Argumenten skickas efter värde och vad som händer med de variabla värdena i proceduren påverkar inte datatillståndet utanför proceduren.
En procedur som accepterar ett variabelt antal argument
### 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
Denna procedur accepterar ett, två eller tre argument: de parametrar vars namn är det första objektet i en lista med två artiklar är valfria. Parametervariablerna ( alpha , beta , gamma ) får så många argumentvärden som är tillgängliga, tilldelade från vänster till höger. Parametervariabler som inte får några argumentvärden istället får sina värden från det andra objektet i listan de ingick i.
Observera att valfria argument måste komma i slutet av argumentlistan. Om argument N-1 är valfritt måste argument N också vara valfritt. Om i ett fall, där användaren har argument N men inte argument N-1 , måste standardvärdet för argument N-1 nämnas uttryckligen före argument N , medan proceduren kallas.
myproc A B C D
# (ERROR) wrong # args: should be "myproc alpha ?beta? ?gamma?"
Proceduren accepterar inte mer än tre argument: Observera att ett användbart felmeddelande som beskriver argumentsyntax automatiskt skapas.
Ett förfarande som accepterar valfritt antal argument
proc myproc args { ... }
proc myproc {args} { ... } ;# equivalent
Om det speciella parameternamnet args är det sista objektet i argumentlistan får det en lista med alla argument på den punkten i kommandoraden. Om det inte finns några är listan tom.
Det kan finnas argument, inklusive frivilliga, innan args :
proc myproc {alpha {beta {}} args} { ... }
Den här proceduren accepterar ett eller flera argument. De två första, om de finns, kommer att konsumeras av alpha och beta : listan med resten av argumenten kommer att tilldelas args .
En procedur som accepterar ett namn / referens till en variabel
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
I detta specifika fall ges proceduren namnet på en variabel i det aktuella omfånget. Inuti en Tcl-procedur är sådana variabler inte automatiskt synliga, men kommandot upvar kan skapa ett alias för en variabel från en annan stacknivå: 1 betyder att den som ringer upp stacknivån, # 0 betyder den globala nivån, etc. I det här fallet betyder stack nivå 1 och namnet foo (från parametervariabeln varName ) låter upvar hitta den variabeln och skapa ett alias som heter var . Varje läs- eller skrivoperation på var händer också med foo i den som ringer upp stacknivån.
Syntaxen {*}
Ibland är det en lista, men kommandot som du vill överföra objekten i listan till kräver för att få varje objekt som ett separat argument. Till exempel: winfo children returnerar en lista med fönster, men kommandot destroy bara en sekvens med fönsternamnsargument.
set alpha [winfo children .]
# => .a .b .c
destroy $alpha
# (no response, no windows are destroyed)
Lösningen är att använda syntaxen {*} :
destroy {*}[winfo children .]
eller
destroy {*}$alpha
Vad {*} -syntaxen gör är att ta följande värde (inget mellanrum mellan!) Och dela objekten i det värdet i kommandoraden som om de var enskilda argument.
Om följande värde är en tom lista, är inget splitsat i:
puts [list a b {*}{} c d]
# => a b c d
Om det finns en eller flera artiklar infogas de:
puts [list a b {*}{1 2 3} c d]
# => a b 1 2 3 c d