【问题标题】:Unable to change the value of the variable无法更改变量的值
【发布时间】:2011-02-02 01:39:28
【问题描述】:

我正在使用一个名为 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

state 的值似乎没有改变。我不确定我在使用 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 还是我的代码有问题...

【问题讨论】:

  • 您是否考虑过incr state 而不是set state [expr {$state + 1}]
  • 是的。刚试了一下……好像不行。
  • 它应该与全局参考

标签: debugging tcl simulation ns2 otcl


【解决方案1】:

编辑:现在了解状态机

首先,您使用的引用语法会给您带来麻烦。您通常应该使用列表构建 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}]}

【讨论】:

  • 感谢您的回答。由于 ns-2 是一个模拟器,我必须重新编译它以合并您建议的更改。我会努力的。至于其他的,我刚刚更新了我的帖子。感谢您的宝贵时间。
  • @Legend,我更新以提供更清晰的答案(b/c 我更仔细地重新阅读了这个问题)。有两个问题需要克服,我只回答了不太重要的一个。这个答案应该可以解决您的问题,而无需更改 ns-2。
  • 谢谢 Trey... 任何有兴趣了解正确代码的人,请在此处查找我的回复。
  • 如果你想逃避一切,你不妨把它放在 {} 中
【解决方案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 返回之后。

【讨论】:

  • 谢谢。用输出更新了我的帖子。似乎不是问题。
【解决方案3】:

我不确定为什么会这样,但它确实有效:

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

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

【讨论】:

  • 查看我的回答,了解它为何起作用(提示:您更改了命令的顺序,这会影响替换的内容)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-27
  • 2022-07-19
  • 2022-06-15
  • 2020-10-11
相关资源
最近更新 更多