尝试访问array
内的expr
时遇到问题。下面显示了重现错误的代码,该代码改编自Donal Fellows对我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
我想修复上面代码中的以下行
.c2 configure -state [expr $cb(c1) ? "disabled" : "normal"]
当我使用上面这行时,我收到以下错误:
can't set "cb(c1)": invalid bareword "disabled" in expression "1? disabled : normal";
答案 0 :(得分:3)
您应该始终在表达式周围放置{
大括号}
,因为这会停止双重替换,让"
引号"
完成正确的目的。您还可以通过这样做提高代码的安全性和速度,至少从Tcl 8.0开始(十多年前);在此之前,性能原因意味着许多人省略了括号,但这是一个非常糟糕的习惯。
简而言之,请勿使用:
.c2 configure -state [expr $cb(c1) ? "disabled" : "normal" ]
而是使用它:
.c2 configure -state [expr {$cb(c1) ? "disabled" : "normal"}]
答案 1 :(得分:2)
.c2 configure -state [expr {$cb(c1) ? "disabled" : "normal"}]