No se puede cambiar el valor de la variable
-
22-09-2019 - |
Pregunta
Estoy usando un simulador de eventos discretos llamados ns-2 que fue construida con Tcl y C++.Yo estaba tratando de escribir algo de código en 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
Aquí está el resultado:
At 0.0 value of state is: 0
Changed value of state to 0
At 2.0 values of state is: 0
El valor de estado parece no cambiar.No estoy seguro de si estoy haciendo algo mal en el uso de TCL.Alguien tiene una idea de qué podría estar pasando mal aquí?
EDITAR:Gracias por la ayuda.En realidad, el ns-2 es algo más que yo no tengo mucho control (a menos que me vuelva a compilar el simulador en sí).He probado las sugerencias y aquí está el resultado:
para el código:
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
el resultado es:
At 0.0 value of state is: 0
At 1 changed value of state to 1
At 2.0 values of state is: 0
Y para el código:
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
el resultado es:
At 0.0 value of state is: 0
At 1.0 values of state is: 1
At 2.0 values of state is: 0
Parece que no funciona...No estoy seguro si es un problema con ns2 o mi código...
Solución
Editar:ahora comprender el estado de la máquina
En primer lugar, la cotización de la sintaxis está utilizando va a meter en problemas.En general usted debe construir Tcl comandos de uso de la lista, lo que asegura que Tcl no se expanda lo que no queremos que se expanda.
Su at-now
las llamadas son la sustitución de la state
variable cuando usted hace la llamada (es decir,cuando el valor no se modifica y 0.Lo que quiero es:
$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"}
Parece que su changeVal
está correctamente escrita (en la primera versión había algunos de la misma sustitución de problemas), así como el hecho de que estaban pasando en las referencias de variable que se utiliza a nivel local, y por lo tanto no establecer el estado global.
La solución a parte de la primera versión de la pregunta - El uso global de referencias, y cita tanto el [
y $
para evitar la sustitución en el punto de la llamada:
$ns at-now "set ::state \[expr {\$::state + 1}\]"
o, usando llaves:
$ns at-now {set ::state [expr {$::state + 1}]}
Otros consejos
El problema es que está sustituyendo el valor de las variables de inmediato, y no en el momento de ser evaluado código. Es necesario posponer la sustitución. Por lo tanto, en lugar de:
$ns at 2.0 "puts \"At 2.0 values of state is: $state\""
Haga lo siguiente:
$ns at 2.0 {puts "At 2.0 values of state is: $state"}
Es una buena práctica para poner algo más complejo que una simple llamada de un comando sin sustitución en un procedimiento cuando se hace una llamada como ésta. Mucho más fácil de hacer que funcione bien.
[EDIT]
Además, el at-now
se sigue posponiendo haciendo su cuerpo hasta después de que los rendimientos actuales at
.
No estoy seguro de por qué esto funciona, pero funciona:
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
Salida:
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 alguien conoce una explicación, que sería grande.