2011-08-10 27 views
1

我在嘗試訪問expr中的array時遇到問題。下面顯示了重現錯誤的代碼,它是根據Donal Fellows回答我的earlier question而得出的。Tcl/Tk:在expr中使用數組

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";

回答

3

您應該始終將{大括號}放在表達式中,因爲這會停止雙重替換,並且會使"引用"達到其正確的目的。通過這樣做,您還可以提高代碼的安全性,並且自從至少Tcl 8.0(十多年前)以來已經完成了這一工作。在此之前,表現的原因意味着許多人都省略了括號,但那是一種真正可怕的習慣。

總之,不要使用:

.c2 configure -state [expr $cb(c1) ? "disabled" : "normal" ] 

而要用這樣的:

.c2 configure -state [expr {$cb(c1) ? "disabled" : "normal"}] 
2

你有沒有嘗試 .c2 configure -state [expr {$cb(c1) ? "disabled" : "normal"}]

+1

,而在解決這個答案的提示,這將是一個更好的答案(也可能得到更多的投票)如果你解釋_why_你的解決方案的作品。 –

+0

你是對的@Bryan Oakley。下次會這樣做。 Donal Fellows很好地解釋了這一點。這是爲了確保在應用expr之前先執行後一部分。 –