2010-03-29 133 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