I am running into problems while trying to access array inside an expr. The code which reproduces the error is shown below which is adapted from Donal Fellows answer to my earlier question.
namespace eval Ns {
}
proc Ns::main_routine {} {
global cb
array set cb {
c1 0
c2 0
c3 0
c4 0
}
checkbutton .c1 -text "C1" -variable cb(c1)
checkbutton .c2 -text "C2" -variable cb(c2)
checkbutton .c3 -text "C3" -variable cb(c3)
checkbutton .c4 -text "C4" -variable cb(c4)
grid .c1 -sticky w
grid .c2 -sticky w
grid .c3 -sticky w
grid .c4 -sticky w
# _After_ initializing the state...
trace add variable cb(c1) write Ns::reconfigureButtons
trace add variable cb(c2) write Ns::reconfigureButtons
trace add variable cb(c3) write Ns::reconfigureButtons
trace add variable cb(c4) write Ns::reconfigureButtons
}
proc Ns::reconfigureButtons args {
global cb
# this one works
set state "normal"
if { $cb(c1) } {
set state "disabled"
}
.c2 configure -state $state
# this one does not
#.c2 configure -state [expr $cb(c1) ? "disabled" : "normal"]
#.c4 configure -state [expr $cb(c1)||$cb(c3) ? "disabled" : "normal"]
}
Ns::main_routine
I want to fix the following line in the above code
.c2 configure -state [expr $cb(c1) ? "disabled" : "normal"]
When I use the above line I get the following error:
can't set "cb(c1)": invalid bareword "disabled" in expression "1? disabled : normal";
You should always put
{braces}around expressions, as that stops double substitution, leaving the"quotes"to do their proper purpose. You also boost the security and speed of your code by doing that, and have done since at least Tcl 8.0 (over a decade ago); before that, performance reasons meant that many people omitted braces, but that was a truly terrible habit.In short, don’t use:
But rather use this: