Reputation: 33
I am having trouble creating a list of lists that contains a mixture of text and variables in TCL. I have a user input variable that I then want to plug into a list. I will skip the user select option for brevity.
set a 0.1
set b 20.0
set c {
{text1 text2 $a text3}
{text4 text5 $b text6}
}
foreach i $c {
set CheckVal [lindex $i 2]
puts "Threshold is $CheckVal"
}
Resultant output:
Threshold is $a
Threshold is $b
Desired output:
Threshold is 0.1
Threshold is 20.0
Upvotes: 3
Views: 8339
Reputation: 4813
While the methods suggested by Peter Lewerin work, they should only be used as a last resort. Normally you would use some of the commands that operate on lists to create your list of lists. I believe that is what glenn jackman was alluding to.
Depending on your actual code, I would probably use list
and/or lappend
:
set c {}
lappend c \
[list text1 text2 $a text3] \
[list text4 text5 $b text6]
Then the foreach will work as you wrote it.
Upvotes: 2
Reputation: 13252
Two alternatives are
set a 0.1
set b 20.0
set c {
{text1 text2 a text3}
{text4 text5 b text6}
}
foreach i $c {
set CheckVal [lindex $i 2]
puts "Threshold is [set $CheckVal]"
}
Store the variable name instead of the value, and get the value by a two-step substitution ($$Checkval
doesn't work, but [set $CheckVal]
does) in the puts
invocation.
set a 0.1
set b 20.0
set c {
{text1 text2 $a text3}
{text4 text5 $b text6}
}
foreach i $c {
set CheckVal [lindex $i 2]
puts [subst "Threshold is $CheckVal"]
}
This is double substitution rather than two-step substitution. It looks simple, but subst
is actually a bit tricky and is almost a last-resort technique.
Regardless of which solution you use, this kind of scheme where you store a reference to a variable value in a structure is fragile since it depends on the original variable being in scope and still existing when the reference is dereferenced. At the very least, you should store a qualified name (namespace and name) in your list. If the variable is a local variable, you need to use it during the same call as when it was stored (or from further up the call stack using upvar
, but don't go there).
Upvotes: 1