Tcl / Tk:使用带expr的数组

时间:2011-08-10 13:35:31

标签: arrays tcl tk

尝试访问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";

2 个答案:

答案 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"}]