I'm redefining Tcl's set
command to allow multiple assignments at once. However, once I try to use the variables, it reports an "undefined variable" error. Here are the two ways I've tried so far:
proc set args {
uplevel foreach {*}$args break
}
proc set {l1 l2} {
uplevel foreach $l1 $l2 break
}
I performed an llength
on $args
and it did report a list of two elements. I'm quite confused about this behavior.
I'm calling it like so:
set {a b c d} {e f g h}
set {a s d f} {q w e r t y}
*Edit:
Did a bit more tinkering with it. I found a way to make it work (for the most part, because extra values are silently discarded, but that's irrelevant to the original question), but I'm still confused about WHY this way worked but the others didn't:
proc set {l L} {
uplevel foreach [list $l] [list $L] break
}
uplevel
joins its arguments as if they had been passed to concat
, which among other things, says
If all of the arguments are lists, this has the same effect as concatenating them into a single list.
So your first version becomes
foreach a b c d e f g h break
leaving a
set to b, c
set to d, and so on. Your second version ends up doing the same; the two lists are flattened out and their elements become individual arguments to foreach
. The third version, wrapping the arguments in list
, becomes your intended
foreach {a b c d} {e f g h} break
the outer list is stripped, but the inner ones remain.
As an aside, I would use a different name than set
, or define it in a non-global namespace, unless you also intend to also support the single-argument version of set
that returns the current value of a variable. Way less confusing that way.