Juan
Juan

Reputation: 3766

Passing list to Tcl procedure

What is the canonical way to pass a list to a Tcl procedure?

I'd really like it if I could get it so that a list is automatically expanded into a variable number of arguments.

So that something like:

set a {b c}
myprocedure option1 option2 $a

and

myprocedure option1 option2 b c

are equivalent.

I am sure I saw this before, but I can't find it anywhere online. Any help (and code) to make both cases equivalent would be appreciated.

Is this considered a standard Tcl convention. Or am I even barking up the wrong tree?

Upvotes: 17

Views: 31820

Answers (3)

dougcosine
dougcosine

Reputation: 171

It might be useful to note that passing your command to catch will also solve this problem:

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

This should probably only be used if you want to handle errors in myprocedure at this point in your code so that you don't have to worry about rethrowing any errors that get caught.

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246744

To expand on RHSeeger's answer, you would code myprocedure with the special args argument like this:

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"
}

Upvotes: 0

RHSeeger
RHSeeger

Reputation: 16262

It depends on the version of Tcl you're using, but: For 8.5:

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

For 8.4 and below:

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

Upvotes: 23

Related Questions