Reputation: 219
I tried to do the following in TCL and got the following error "list must be an even number of elements" because $args is seen as one list when passed to B.
Is there a clever way of passing $args to B?
proc A {a args} {
#call B and pass it args
B 2 $args
}
proc B {b args} {
set options(-flag1) 0
set options(-option) serial
array set options $args
#use options
}
Upvotes: 0
Views: 1898
Reputation: 13282
Try this:
B 2 {*}$args
If we simplify the procedures a bit:
proc A args {
puts [info level 0]
B $args
}
proc B args {
puts [info level 0]
}
If we call A
with some values, B
will receive those values packaged in a list. This list, being a single item in args
, is not fit to pass to array set
, since that command needs an even-sized list.
% A a b c d
A a b c d
B {a b c d}
Change the invocation of B
to this:
proc A args {
puts [info level 0]
B {*}$args
}
Now, if we call A
, each argument to A
will become a distinct argument to B
, and $args
can now be used as an argument to array set
.
% A a b c d
A a b c d
B a b c d
As nurdglaw points out, Tcl 8.4 or older does not have the {*}
syntax, which means eval
must be used to invoke B
. One way to do it is
eval [linsert $args 0 B]
but one could also use the slightly less secure (it can lead to loss of argument structure)
eval B $args
Tcl 8.4 isn't supported any more, and there is every reason to upgrade to 8.5 or 8.6.
Documentation: eval, info, linsert, proc, puts, {*}
Upvotes: 3