2010-03-29 18 views
1

J'utilise un simulateur d'événement discret appelé ns-2 qui a été construit en utilisant Tcl et C++. Je tentais d'écrire du code dans TCL:Impossible de changer la valeur de la variable

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 

est ici 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 suis pas sûr si je fais quelque chose de mal dans l'utilisation de TCL. Quelqu'un a une idée de ce qui pourrait mal se passer ici?

EDIT: Merci pour l'aide. En fait, ns-2 est quelque chose sur lequel je n'ai pas beaucoup de contrôle (sauf si je recompile 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:

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:

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 ...

+2

avez-vous considéré 'incr state' au lieu de' set state [expr {$ state + 1}] '? –

+0

Oui. Juste essayé ... ne semble pas fonctionner. – Legend

+0

il devrait avec les refs globaux –

Répondre

2

Edit: maintenant comprendre la machine d'état

D'abord, la syntaxe vous citant L'utilisation va vous causer des ennuis. Vous devriez généralement construire des commandes Tcl en utilisant list, ceci garantit que Tcl will not expand what you don't want it to expand.

Vos at-now appels remplacent la variable state lorsque vous faites l'appel (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 quelques-uns des mêmes problèmes de substitution), ainsi que le fait que vous passiez dans des références variables qui seraient utilisées localement, et donc ne définissant pas l'état global

Solution à la partie de la première version de la question - Utiliser des références globales, et les devis du [ 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}]} 
+0

Merci pour la réponse. Comme ns-2 est un simulateur, je dois le recompiler pour incorporer les changements que vous avez suggérés. J'y travaillerai. En ce qui concerne les autres choses, je viens de mettre à jour mon post. Merci pour votre temps. – Legend

+0

@Legend, j'ai mis à jour pour fournir une réponse plus claire (b/c je relis la question plus attentivement). Il y avait deux problèmes à surmonter, et je viens de répondre le moins important. Cette réponse devrait répondre à vos préoccupations sans avoir besoin de changer ns-2. –

+0

Merci Trey ... Pour toute personne intéressée à connaître le bon morceau de code, cherchez ma réponse ici. – Legend

2

Le problème est que vous êtes en substituant la valeur de vos variables immédiatement, et non au moment de l'évaluation du code. 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 de le faire fonctionner correctement.

[EDIT]
En outre, le at-now reporte encore faire son corps jusqu'à ce que les at actuels des rendements.

+0

Merci. Mise à jour de mon message avec la sortie. Ne semble pas être le problème. – Legend

0

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.

+0

Voir ma réponse pour savoir pourquoi cela fonctionne (indice: vous avez changé l'ordre des commandes, ce qui a affecté ce qui a été substitué). –