Невозможно изменить значение переменной - PullRequest
1 голос
/ 29 марта 2010

Я использую имитатор дискретных событий 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 ]

2 голосов
/ 29 марта 2010

Проблема в том, что вы подставляете значение своих переменных немедленно, а не во время оценки кода. Вам нужно отложить замену. Таким образом, вместо:

$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 голосов
/ 29 марта 2010

Редактировать: теперь понимание конечного автомата

Во-первых, синтаксис цитирования, который вы используете, доставит вам неприятности. Обычно вы должны создавать команды Tcl, используя список, это гарантирует, что Tcl не будет расширять то, что вы не хотите, чтобы оно расширяло .

Ваши 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 голосов
/ 29 марта 2010

Я не уверен, почему это работает, но работает:

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

Если кто-нибудь знает объяснение, это было бы замечательно.

...