2010-03-29 106 views
1

我正在使用名爲ns-2的使用Tcl和C++構建的離散事件模擬器。我試圖寫一些代碼在TCL:無法更改變量的值

set ns [new Simulator] 

set state 0 

$ns at 0.0 "puts \"At 0.0 value of state is: $state\"" 
$ns at 1.0 "changeVal" 
$ns at 2.0 "puts \"At 2.0 values of state is: $state\"" 

proc changeVal {} { 
    global state 
    global ns 
    $ns at-now "set state [expr $state+1]" 
    puts "Changed value of state to $state" 
} 

$ns run 

下面是輸出:

At 0.0 value of state is: 0 
Changed value of state to 0 
At 2.0 values of state is: 0 

狀態的價值似乎並沒有改變。我不確定我是否在使用TCL方面做錯了什麼。任何人都有一個想法,可能會出現什麼問題?

編輯:謝謝你的幫助。實際上,ns-2是我無法控制的東西(除非我自己重新編譯模擬器)。我嘗試了建議和這裏的輸出:

的代碼:

set ns [new Simulator] 

set state 0 

$ns at 0.0 "puts \"At 0.0 value of state is: $state\"" 
$ns at 1.0 "changeVal" 
$ns at 9.0 "puts \"At 2.0 values of state is: $state\"" 

proc changeVal {} { 
    global ns 
    set ::state [expr {$::state+1}] 
    $ns at-now "puts \"At [$ns now] changed value of state to $::state\"" 
} 

$ns run 

輸出爲:

At 0.0 value of state is: 0 
At 1 changed value of state to 1 
At 2.0 values of state is: 0 

而對於代碼:

set ns [new Simulator] 

set state 0 

$ns at 0.0 "puts \"At 0.0 value of state is: $state\"" 
$ns at 1.0 "changeVal" 
$ns at 9.0 "puts \"At 2.0 values of state is: $state\"" 

proc changeVal {} { 
    global ns 
    set ::state [expr {$::state+1}] 
    $ns at 1.0 {puts "At 1.0 values of state is: $::state"} 
} 

$ns run 

輸出是:

At 0.0 value of state is: 0 
At 1.0 values of state is: 1 
At 2.0 values of state is: 0 

似乎不工作...不知道它與NS2和我的代碼有問題...

+2

您是否考慮過'incr state'而不是'set state [expr {$ state + 1}]'? – 2010-03-29 15:37:56

+0

是的。剛剛嘗試過......似乎沒有工作。 – Legend 2010-03-29 15:44:29

+0

它應該與全球參考 – 2010-03-29 23:10:33

回答

2

編輯:現在理解了狀態機

首先,引用語法你'使用會給你帶來麻煩。你通常應該使用列表建立Tcl命令,這確保了Tcl will not expand what you don't want it to expand。當你撥打電話

at-now調用替換state變量(即當值不變,0。你想要的是:

$ns at-now 0.0 {puts "At 0.0 value of state is: $::state"} 
$ns at-now 2.0 {puts "At 2.0 value of state is: $::state"} 

它看起來像你的changeVal編寫正確(第一版本有一些相同的替換問題),以及您正在傳遞將在本地使用的可變引用的事實,因此不設置全局狀態。

解決第一版問題的一部分 - 使用全局引用,並同時報出[$防止替代在調用點:

$ns at-now "set ::state \[expr {\$::state + 1}\]" 

,或者使用大括號:

$ns at-now {set ::state [expr {$::state + 1}]} 
+0

感謝您的答案。由於ns-2是一個模擬器,我不得不重新編譯它以結合您所建議的更改。我會努力的。至於其他的事情,我只是更新了我的文章。謝謝你的時間。 – Legend 2010-03-29 15:45:17

+0

@Legend,我更新了一個更清晰的答案(b/c我更仔細地重讀了這個問題)。有兩個問題需要克服,我只是回答了一個不太重要的問題。這個答案應該解決你的問題,而不需要改變ns-2。 – 2010-03-29 16:08:44

+0

感謝Trey ...對於有興趣瞭解正確代碼的人,請在此處查看我的回覆。 – Legend 2010-03-29 19:01:20

2

問題是你代你的變量的值立即,而不是在代碼被評估的時候。你需要推遲替代。因此,而不是:

$ns at 2.0 "puts \"At 2.0 values of state is: $state\"" 

這樣做:

$ns at 2.0 {puts "At 2.0 values of state is: $state"} 

這是很好的做法做這樣一個呼叫時把任何東西不是一個命令的一個簡單的通話更加複雜而不替代的過程。更容易使其正確工作。

[編輯]
此外,at-now仍推遲做它的身體,直到當前的at返回後。

+0

謝謝。用輸出更新我的帖子。似乎不是問題。 – Legend 2010-03-29 15:45:46

0

我不知道爲什麼這個工作,但它的工作原理:

set ns [new Simulator] 

set state 0 

proc changeVal {} { 
    global ns 
    incr ::state 
    $ns at-now {puts "Local::At [$ns now] values of state is: $::state"} 
} 

$ns at 0.0 "puts \"Global::At 0.0 value of state is: $state\"" 
changeVal 
$ns at 9.0 "puts \"Global::At 2.0 values of state is: $state\"" 

$ns run 

輸出:

Global::At 0.0 value of state is: 0 
Local::At 0 values of state is: 1 
Global::At 2.0 values of state is: 1 

如果有人知道一個解釋,那將是巨大的。

+0

查看我的答案爲什麼它的工作原理(提示:你改變了命令的順序,這影響了被替換的命令)。 – 2010-03-29 16:21:11