开发者

Unable to change the value of the variable

I'm using a discrete event simulator called ns-2 that was built using Tcl and C++. I was trying to write some code in 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

Here's the output:

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

The value of state does not seem to change. I am not sure if I am doing something wrong in using TCL. Anyone has an idea as to what might be going wrong here?

EDIT: Thanks for the help. Actually, ns-2 is something over which I do not have much control (unless I recompile the simulator itself). I tried out the su开发者_运维百科ggestions and here's the output:

for the code:

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

the output is:

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

And for the code:

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

the output is:

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

Doesn't seem to work... Not sure if its a problem with ns2 or my code...


Edit: now understanding the state machine

First, the quoting syntax you're using is going to get you in trouble. You should generally build up Tcl commands using list, this ensures that Tcl will not expand what you don't want it to expand.

Your at-now calls are substituting the state variable when you make the call (i.e. when the value is unchanged and 0. What you want is:

$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"}

It looks like your changeVal is properly written (the first version had some of the same substitution problems), as well as the fact that you were passing in variable references that would be used locally, and therefore not setting the global state.

Solution to part of first version of question - Use global references, and quote both the [ and $ to prevent substitution at the point of the call:

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

or, using curly braces:

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


The problem is you're substituting the value of your variables immediately, and not at the time the code is evaluated. You need to postpone the substitution. Thus, instead of:

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

Do this:

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

It's good practice to put anything more complex than a simple call of a command without substitution in a procedure when doing a call like this. Much easier to make it work right.

[EDIT]
Also, the at-now is still postponing doing its body until after the current at returns.


I am not sure why this works but it works:

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

Output:

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

If anyone knows an explanation, that would be great.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜