Re: Necesito ayuda para entender cómo las variables están en el ámbito de las expresionesEl alcance es así: buscar en Local() espacio de nombres si existe, si no busca en Aquí() espacio de nombres si existe, si no busca en Global() espacio de nombres(Además, a veces también verificará los nombres de las columnas de la tabla de datos actual).
Lo que estás haciendo en tu primer guión es poner el nombre "x"n en el Aquí() espacio de nombres con valor "Variable" , luego pon el nombre "exprA"n en el Aquí() espacio de nombres con valor Escribir( "Aquí está la variable: " || x ) , luego pon nombre "exprB"n en el Aquí() espacio de nombres con valor Pegamento( dt1 = Abrir( "$SAMPLE_DATA/Big Class.jmp" ), dt1 << Al cerrar( exprA ) ) .
Finalmente evalúas "exprB"n -- JMP luego intenta resolver este nombre comprobando primero el Local() espacio de nombres (no existe), entonces el Aquí() espacio de nombres y lo encuentra, por lo que ejecuta la expresión almacenada en Según alcance( "aquí", "exprB" ) .
Esto luego carga la tabla y pone ExprA como script de cierre de la ventana.
Dado que este es el final del guión, entonces el Aquí() el espacio de nombres creado para el script se elimina y la memoria se borra.
Cuando cierras la tabla, encuentra el literal ExprA como secuencia de comandos de cierre, luego intenta abarcar el nombre como se indica arriba (en Local() , Aquí() , Global() ), solo que esta vez no hay Aquí() espacio de nombres y no puede encontrar el nombre en ninguno de los tres espacios de nombres, lo que genera un error.
En general, cuando desee agregar una variable como un valor estático a una expresión que se ejecutará en un ámbito diferente, utilice Eval( Eval Expr( ...; Expr( Nombre Expr( val ) ); ... ) ) o algún otro equivalente.
En mi experiencia personal, creo espacios de nombres explícitos para cada secuencia de comandos (anónimos) y luego miro manualmente todas las variables al espacio de nombres respectivo.Luego puedo pasar este espacio de nombres según sea necesario (y, por supuesto, borro y cierro el espacio de nombres cuando el script está listo/la ventana está cerrada).
Algunos ejemplos de cómo se podría hacer que su script funcione son los siguientes:
Names Default To Here( 1 );
x = "Variable";
Eval( Eval Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt1 << OnClose( Write( "\!NHere is variable: " || Expr( x ) ) );
) );
o
Names Default To Here( 1 );
x = "Variable";
exprA = Expr(
Write( "\!NHere is variable: " || x )
);
Eval( Eval Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt1 << OnClose( x = "rather"; Expr( Name Expr( exprA ) ) );
) );
o
Names Default To Here( 1 );
self = New Namespace();
self:x = "Variable";
self:exprA = Expr(
Write( "\!NHere is variable: " || self:x )
);
Eval( Eval Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt1 << OnClose(
Local( {self = Namespace( Expr( self << Get Name ) )},
self:exprA;
Delete Namespaces( Force( 1 ), self )
)
);
) );Tenga en cuenta que, si bien muchos lenguajes de programación crean espacios de nombres locales y los mantienen utilizando contadores de referencia hasta que ya no son necesarios (como Python con funciones y demás), JSL realmente no hace eso y depende del codificador mantener cualquier se necesita persistencia y alcance. El código dentro del <<AL cerrar=""> el mensaje se evalúa en un contexto completamente separado del script que lo creó sin gestión de nombres o ámbitos.</AL>
Espero que esto ayude, puede ser un poco confuso!!
Re: Necesito ayuda para entender cómo las variables están en el ámbito de las expresionesJordan, muchas gracias, explica el comportamiento. Me gusta su forma propuesta con los espacios de nombres, ya que el script real tiene muchas tablas que compartirían variables en sus declaraciones OnClose.
¿Me pueden ayudar a entender el siguiente fragmento de código:
Local( {self = Namespace( Expr( self << Get Name ) )},
self:exprA;
Delete Namespaces( Force( 1 ), self )
)Local resuelve los nombres de las variables locales, ¿qué significa eso? ¿Por qué necesita definir algunas variables entre corchetes? ¿Cuál es el propósito? (tanto el índice de secuencias de comandos como la documentación no dicen mucho al respecto).
Re: Necesito ayuda para entender cómo las variables están en el ámbito de las expresionesRespuesta corta: evita que los nombres sobrescriban cualquier cosa fuera del Local() bloquear.
Respuesta larga:
Para mis funciones las escribo así:
some function = Function( {arg1, arg2, etc},
{Default Local},
self:arg1 = arg1;
self:arg2 = arg2;
//do something amazing!
//call a method:
self:call method
);
call method = Function( {},
//do something else amazing!
1
)
Luego uso la metaprogramación para definir ser e inyectar una referencia en cada función, que la transforma en algo como:
self:some function = Function( {arg1, arg2, etc},
{Default Local},
self = Namespace( "#48" );
self:arg1 = arg1;
self:arg2 = arg2;
//do something amazing!
//call a method:
self:call method
);
self:call method = Function( {},
{self},
self = Namespace( "#48" );
//do something else amazing!
1
)Esto crea algo que es muy similar a las clases de Python (mi código es muy diferente de las declaraciones anteriores, pero conceptualmente similar).Lo que no quiero que pase nunca es tener la referencia ser ser sobrescrito por cualquier otro valor.
Imagina que en una función tengo un Espera( 1 ) por alguna razón, y durante esa fase de espera alguien cierra una tabla que tiene un script adjunto que redefine ser -- cuando la declaración de espera se hace entonces ser ahora se refiere a una variable diferente y se produce el caos.
El Local() La función crea un bloque local y cualquier variable definida en el primer argumento (la lista) es local para ese bloque, como
Names Default to Here( 1 );
a = 1;
b = 4;
Print( "Before Local Block:" );
Show( a, b );
Local(
{local_var1, local_var2, b},
local_var1 = 4;
local_var2 = 2;
b = 9;
Print( "Inside Local Block:" );
Show( local_var1, local_var2, a, b );
a = 5;
);
Print( "After Local Block:" );
Show( Try( local_var1, Empty() ), Try( local_var2, Empty() ), a, b )
/*:
"Before Local Block:"
a = 1;
b = 4;
"Inside Local Block:"
local_var1 = 4;
local_var2 = 2;
a = 1;
b = 9;
"After Local Block:"
Try(local_var1, Empty()) = Empty();
Try(local_var2, Empty()) = Empty();
a = 5;
b = 4;Aquí redefino ambos a y b dentro del bloque local, pero b fuera del bloque local no se ve afectado mientras a es.Poniendo ser como una variable local es el enfoque más seguro.
Necesita ayuda para entender cómo las variables están en el ámbito de las expresionesHola a todos,
Tengo un script de ejemplo simple. ¿Alguien puede explicarme cuáles son los alcances de las variables aquí y por qué funciona de una manera y no de otra?
Aquí está el guión inicial:
Names default to here(1);
Clear Globals();
x="Variable";
exprA = Expr(Write("Here is variable: "||x));
exprB = Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );dt1 << OnClose(exprA));
exprB;La idea es que abro la tabla y le doy una expresión que necesita para ejecutarse cuando está cerrada. Expression evalúa y cambia (no en este ejemplo) algunas variables del script.
La forma en que está escrito no funciona, no pasa nada, pero en mi guión real simplemente dice que no puede encontrar una referencia.
Bien, intentemos hacer que ExprA sea global:
Names default to here(1);
Clear Globals();
x="Variable";
::exprA = Expr(Write("Here is variable: "||x));
exprB = Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );dt1 << OnClose(exprA));
exprB;Ahora sí ve la expresión, pero sigue sin funcionar, porque ahora no ve la variable x.
Ok, hagamos x global también:
Names default to here(1);
Clear Globals();
::x="Variable";
::exprA = Expr(Write("Here is variable: "||x));
exprB = Expr(
dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );dt1 << OnClose(exprA));
exprB;Ahora funciona:
Scriptable[]Here is variable: Variable
// Close Data Table: Big Class
Close( "Big Class" );
La pregunta: ¿por qué funciona de esta manera y no funciona de la manera inicial? Me miré, debería haber funcionado.
No me gusta usar variables globales en este script, ¿alguna otra forma de hacerlo funcionar?
Modelado Estadístico AvanzadoAutomatización y secuencias de comandosInvestigación del Consumidor y del MercadoAcceso a los datosFusión y limpieza de datosDiseño de experimentosLa personalización en masaIngeniería de Calidad y Procesos