Re: Serve aiuto per capire in che modo le variabili hanno l'ambito nelle espressioniL'ambito va così: cerca dentro Locale() namespace se esiste, se non cerca in Qui() namespace se esiste, se non cerca in Globale() spazio dei nomi.(Inoltre, a volte controllerà anche i nomi delle colonne della tabella di dati corrente).
Quello che stai facendo nel tuo primo script è inserire il nome "x"n dentro Qui() spazio dei nomi con valore "Variabile" , quindi inserisci il nome "esprA"n dentro Qui() spazio dei nomi con valore Write( "Ecco la variabile: " || x ) , quindi inserisci il nome "esprB"n dentro Qui() spazio dei nomi con valore Glue(dt1 = Open("$SAMPLE_DATA/Big Class.jmp" ), dt1 << Alla chiusura( exprA ) ) .
Alla fine valuti "esprB"n -- JMP tenta quindi di risolvere questo nome controllando prima il Locale() namespace (non esiste), quindi il Qui() namespace e lo trova, quindi esegue l'espressione archiviata As Scoped( "qui", "exprB" ) .
Questo quindi carica la tabella e mette espr come script di chiusura della finestra.
Poiché questa è la fine dello script, il file Qui() lo spazio dei nomi creato per lo script viene eliminato e la memoria cancellata.
Quando chiudi il tavolo, trova il letterale espr come script di chiusura, quindi tenta di definire l'ambito del nome come sopra (in Locale() , Qui() , Globale() ), solo che questa volta non c'è Qui() namespace e non riesce a trovare il nome in nessuno dei tre namespace, generando così un errore.
In generale, quando vuoi aggiungere una variabile come valore statico a un'espressione che verrà eseguita in un ambito diverso, usa Eval( Eval Espr( ...; Espr( Nome Espr( val ) ); ... ) ) o qualche altro equivalente.
Nella mia esperienza personale creo spazi dei nomi espliciti per ogni script (anonimo), quindi oscillo manualmente tutte le variabili nel rispettivo spazio dei nomi.Posso quindi passare questo spazio dei nomi in base alle esigenze (e ovviamente azzero e chiudo lo spazio dei nomi quando lo script è terminato / la finestra è chiusa).
Alcuni esempi di come il tuo script potrebbe essere fatto funzionare sono i seguenti:
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 )
)
);
) );Nota che mentre molti linguaggi di programmazione creano spazi dei nomi locali e li tengono in giro usando i contatori di riferimento finché non sono più necessari (come Python con funzioni e simili), JSL non lo fa davvero e spetta al programmatore mantenerne persistenza e scoping necessari. Il codice all'interno del <<IN chiusura=""> il messaggio viene valutato in un contesto completamente separato rispetto allo script che lo ha creato senza gestione di nomi o ambiti.</IN>
Spero che questo aiuti, può creare un po' di confusione!!
Re: Serve aiuto per capire in che modo le variabili hanno l'ambito nelle espressioniJordan, grazie mille, spiega il comportamento. Mi piace il modo in cui hai proposto gli spazi dei nomi, poiché lo script reale ha molte tabelle che condividerebbero le variabili nelle loro istruzioni OnClose.
Potete aiutarmi a capire il seguente pezzo di codice:
Local( {self = Namespace( Expr( self << Get Name ) )},
self:exprA;
Delete Namespaces( Force( 1 ), self )
)Local risolve i nomi in variabili locali, cosa significa? Perché è necessario definire alcune variabili tra parentesi graffe, qual è lo scopo? (sia l'indice di script che la documentazione non dicono molto a riguardo).
Ri: Ho bisogno di aiuto per capire come le variabili sono definite nelle espressioniRisposta breve: impedisce ai nomi di sovrascrivere qualsiasi cosa al di fuori del file Locale() bloccare.
Risposta lunga:
Per le mie funzioni le scrivo così:
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
)
Quindi uso la meta-programmazione per definire se stesso e iniettare un riferimento in ogni funzione, che lo trasforma in qualcosa del tipo:
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
)Questo crea qualcosa che è molto simile alle classi Python (il mio codice è molto diverso dalle affermazioni precedenti, ma concettualmente simile).La cosa che voglio non accada mai è avere il riferimento se stesso essere sovrascritto da qualsiasi altro valore.
Immagina che in una funzione io abbia a Aspetta( 1 ) funzione per qualche motivo e durante quella fase di attesa qualcuno chiude una tabella a cui è allegato uno script che ridefinisce se stesso -- quando l'istruzione wait viene eseguita, then se stesso ora fa riferimento a una variabile diversa e ne consegue il caos.
IL Locale() La funzione crea un blocco locale e tutte le variabili definite nel primo argomento (l'elenco) sono locali a quel blocco, ad esempio
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;Qui ridefinisco entrambi UN E B all'interno del blocco locale, ma B al di fuori del blocco locale non è interessato mentre UN È.Mettendo se stesso come variabile locale è l'approccio più sicuro.
Hai bisogno di aiuto per capire come le variabili sono delimitate nelle espressioniCiao a tutti,
Ho un semplice script di esempio. Qualcuno può spiegarmi quali sono gli ambiti per le variabili qui e perché funziona in un modo e non in un altro?
Ecco lo script iniziale:
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;L'idea è che apro table e gli do un'espressione di cui ha bisogno per essere eseguito quando è chiuso. L'espressione valuta e modifica (non in questo esempio) alcune variabili dallo script.
Il modo in cui è scritto non funziona: non succede nulla, ma nella mia vera sceneggiatura dice solo che non riesce a trovare un riferimento.
Ok, proviamo a rendere ExprA globale:
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;Ora vede l'espressione, ma ancora non funziona, perché ora non vede la variabile x.
Ok, rendiamo anche x globale:
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;Ora funziona:
Scriptable[]Here is variable: Variable
// Close Data Table: Big Class
Close( "Big Class" );
La domanda: perché funziona in questo modo e non funziona nel modo iniziale? Ho pensato che avrebbe dovuto funzionare.
Non mi piace usare le variabili globali in questo script - qualche altro modo per farlo funzionare?
Modellazione statistica avanzataAutomazione e scriptingConsumatori e ricerche di mercatoAccesso ai datiMiscelazione e pulizia dei datiProgettazione di esperimentiPersonalizzazione di massaQualità e ingegneria di processo