无法更改变量的值

时间:2010-03-29 14:12:44

标签: debugging tcl simulation ns2 otcl

我正在使用一个名为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或我的代码是否有问题......

3 个答案:

答案 0 :(得分:2)

编辑:现在了解状态机

首先,您使用的引用语法会让您遇到麻烦。您通常应该使用list构建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}]}

答案 1 :(得分: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返回。

答案 2 :(得分: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

如果有人知道解释,那就太棒了。