2009-10-20 10 views
11

Quelle est la manière canonique de passer une liste à une procédure Tcl? Je voudrais vraiment si je pouvais l'obtenir afin qu'une liste soit automatiquement étendue dans un nombre variable d'arguments.Passer la liste à la procédure Tcl

Alors que quelque chose comme:

set a {b c} 
myprocedure option1 option2 $a 

et

myprocedure option1 option2 b c 

sont équivalentes.

Je suis sûr que j'ai déjà vu ça, mais je ne le trouve nulle part en ligne. Toute aide (et code) pour rendre les deux cas équivalents serait appréciée. Est-ce considéré comme une convention Tcl standard? Ou suis-je même aboyer le mauvais arbre?

+0

Pouvez-vous ajouter le mot "unwrap" (meilleur que dans "unwrap arguments") quelque part dans votre grande question? J'ai eu du mal à le trouver :-) – cfi

Répondre

14

Cela dépend de la version de Tcl que vous utilisez, mais: 8,5:

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

Pour 8.4 et ci-dessous:

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

... bien que je trouve personnellement \ $ option1 \ $ option2 plus préférable à [liste $ option1] [liste $ optio2]. Il montre plus attentivement l'intention - votre intention n'est pas de créer des listes à un élément, votre intention est d'empêcher (ou de protéger contre) une ronde supplémentaire de substitution pour ces variables. –

+0

La façon canonique de faire ceci pour 8.4 et ci-dessous est: 'eval [linsert $ mylist 0 myprocedure options1 option2]' –

+2

Je ne suis pas d'accord que canonique (mais peut-être avons-nous des canons différents?). C'est sans doute le plus sûr mais c'est moins lisible que \ $ option1 \ $ option2 et encore une fois obscurcit ce que vous essayez réellement d'accomplir. –

0

Pour développer la réponse de RHSeeger, vous coderez myProcedure avec l'argument args spécial comme celui-ci:

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

Je ne suis pas d'accord avec le fait que vous devez nécessairement coder myprocedure pour prendre un nombre variable d'arguments (c.-à-d. Utiliser «args»). Que vous le fassiez dépend entièrement du fait que vous en ayez besoin ou non pour prendre un nombre variable d'entrées, et non pas de la façon dont un appelant particulier arrive à avoir ses entrées disponibles. – RHSeeger

0

Il pourrait être utile de noter que le passage de votre commande à catch également résoudre ce problème:

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

Cela devrait probablement être utilisé si vous voulez gérer les erreurs dans MaProcédure à ce point dans votre code afin que vous n » Je dois m'inquiéter de republier les erreurs qui se sont accumulées.