2009-10-20 8 views
11

Was ist der kanonische Weg, eine Liste an eine Tcl-Prozedur zu übergeben?Übergeben der Liste an das Tcl-Verfahren

Ich würde es wirklich gerne, wenn ich es bekommen könnte, so dass eine Liste automatisch in eine variable Anzahl von Argumenten erweitert wird.

Damit so etwas wie:

set a {b c} 
myprocedure option1 option2 $a 

und

myprocedure option1 option2 b c 

gleichwertig sind.

Ich bin mir sicher, dass ich das schon einmal gesehen habe, aber ich kann es nirgendwo online finden. Jede Hilfe (und Code), um beide Fälle äquivalent zu machen, würde geschätzt werden.

Wird dies als Standard-Tcl-Konvention betrachtet? Oder belle ich sogar den falschen Baum an?

+0

Ca fügen Sie das Wort "unwrap" (am besten wie in "unwrap arguments") irgendwo in Ihrer großen Frage hinzu? Ich fand es schwierig, es zu finden :-) – cfi

Antwort

14

Es hängt von der Version von Tcl Sie verwenden, aber: Für 8.5:

set mylist {a b c} 
myprocedure option1 option2 {*}$mylist 

Für 8.4 und unten:

set mylist {a b c} 
eval myprocedure option1 option2 $mylist 
# or, if option1 and 2 are variables 
eval myprocedure [list $option1] [list $option2] $mylist 
# or, as Bryan prefers 
eval myprocedure \$option1 \$option2 $mylist 
+1

... obwohl ich persönlich \ $ option1 \ $ option2 mehr vorzuziehen zu [list $ option1] [list $ optio2]. Es zeigt mehr Absicht - Ihre Absicht ist es nicht, Listen mit einem Element zu erstellen, Ihre Absicht ist es, eine zusätzliche Runde von Substitutionen für diese Variablen zu verhindern (oder davor zu schützen). –

+0

Der kanonische Weg, dies für 8.4 und darunter zu tun, ist: 'eval [linsert $ mylist 0 myprocedure options1 option2]' –

+2

Ich stimme nicht zu, dass das kanonisch ist (aber vielleicht haben wir andere Kanons?). Es ist wohl am sichersten, aber es ist weniger lesbar als \ $ option1 \ $ option2 und wieder etwas verdeckt, was Sie tatsächlich erreichen wollen. –

0

auf RHSeeger Antwort zu erweitern, würden Sie codieren MyProcedure mit dem speziellen args Argument wie folgt aus:

proc myprocedure {opt1 opt2 args} { 
    puts "opt1=$opt1" 
    puts "opt2=$opt2" 
    puts "args=[list $args]" ;# just use [list] for output formatting 
    puts "args has [llength $args] elements" 
} 
+0

Ich stimme nicht zu, dass Sie unbedingt myprocedure codieren würden, um eine variable Anzahl von Argumenten zu nehmen (dh, verwenden Sie "args"). Ob Sie dies tun, hängt ganz davon ab, ob Sie eine variable Anzahl von Eingaben benötigen oder nicht, und nicht, wie ein bestimmter Anrufer seine Eingaben zur Verfügung hat. – RHSeeger

0

Es könnte nützlich sein zu beachten, dass Ihr Befehl catch vorbei wird auch dieses Problem lösen:

set a {b c} 
if [catch "myprocedure option1 option2 $a"] { 
    # handle errors 
} 

Dies sollte wahrscheinlich nur verwendet werden, wenn Sie Fehler in myprocedure an dieser Stelle in Ihrem Code zu handhaben wollen, so dass Sie don‘ Ich muss mir Gedanken darüber machen, irgendwelche Fehler, die sich verfangen haben, erneut auszulösen.

Verwandte Themen