Impossible de modifier la valeur de la variable
-
22-09-2019 - |
Question
J'utilise un simulateur d'événements discrets appelé ns-2 qui a été construit en utilisant Tcl et C ++. Je tentais d'écrire du code dans 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
Voici la sortie:
At 0.0 value of state is: 0
Changed value of state to 0
At 2.0 values of state is: 0
La valeur de l'Etat ne semble pas changer. Je ne sais pas si je fais quelque chose de mal dans l'utilisation de TCL. Tout le monde a une idée de ce qui pourrait aller mal ici?
EDIT: Merci pour l'aide. En fait, ns-2 est quelque chose sur lequel je n'ai pas beaucoup de contrôle (à moins que je recompiler le simulateur lui-même). J'ai essayé les suggestions et voici la sortie:
pour le 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
la sortie est la suivante:
At 0.0 value of state is: 0
At 1 changed value of state to 1
At 2.0 values of state is: 0
Et le 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
la sortie est la suivante:
At 0.0 value of state is: 0
At 1.0 values of state is: 1
At 2.0 values of state is: 0
ne semble pas fonctionner ... Je ne sais pas si son problème avec NS2 ou mon code ...
La solution
Edit: maintenant comprendre la machine d'état
D'abord, la syntaxe citant que vous utilisez va vous causer des ennuis. Vous devez construire généralement des commandes Tcl en utilisant la liste, ce qui garantit que Tcl ne sera pas expand Qu'est-ce que vous ne voulez pas d'élargir .
Vos appels at-now
remplacent la variable state
lorsque vous faites l'appel (à savoir lorsque la valeur est inchangée et 0. Ce que vous voulez est:
$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"}
Il semble que votre changeVal
est correctement écrit (la première version avait certains des mêmes problèmes de substitution), ainsi que le fait que vous passiez dans les références variables qui seraient utilisés la mise en place, et donc pas l'état global.
Solution à une partie de la première version de question - Utiliser des références globales, et la citation à la fois [
et $
pour empêcher la substitution au point de l'appel:
$ns at-now "set ::state \[expr {\$::state + 1}\]"
ou, en utilisant des accolades:
$ns at-now {set ::state [expr {$::state + 1}]}
Autres conseils
Le problème est que vous êtes en substituant la valeur de vos variables immédiatement, et non au moment où le code est évalué. Vous devez reporter la substitution. Ainsi, au lieu de:
$ns at 2.0 "puts \"At 2.0 values of state is: $state\""
Pour ce faire:
$ns at 2.0 {puts "At 2.0 values of state is: $state"}
Il est bon de mettre quelque chose de plus complexe qu'un simple appel d'une commande sans substitution dans une procédure lorsque vous faites un appel comme celui-ci. Beaucoup plus facile à le faire fonctionner à droite.
[EDIT]
En outre, le at-now
reporte encore faire son corps jusqu'à ce que après le retour du courant at
.
Je ne sais pas pourquoi cela fonctionne, mais il fonctionne:
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
Sortie:
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
Si quelqu'un connaît une explication, ce serait génial.