Betreff: Brauchen Sie Hilfe, um zu verstehen, wie Variablen in Ausdrücken geltenDas Scoping geht so – Lookup in Lokal() Namespace, falls vorhanden, falls nicht, Suche in Hier() Namespace, falls vorhanden, falls nicht, Suche in Global() Namensraum.(Außerdem werden manchmal auch die Spaltennamen der aktuellen Datentabelle überprüft).
In Ihrem ersten Skript geben Sie den Namen ein "x"n in die Hier() Namensraum mit Wert "Variable" , dann geben Sie den Namen ein "exprA"n in die Hier() Namensraum mit Wert Write( "Hier ist Variable: " || x ) , dann Namen eingeben "exprB"n in die Hier() Namensraum mit Wert Glue( dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" ), dt1 << On Close( exprA ) ) .
Abschließend werten Sie aus "exprB"n -- JMP versucht dann, diesen Namen aufzulösen, indem es zuerst die Lokal() Namespace (es existiert nicht), dann die Hier() Namespace und es findet ihn – also führt es den darin gespeicherten Ausdruck aus As Scoped( "hier", "exprB" ) .
Dieser lädt dann die Tabelle und setzt exprA als schließendes Skript für das Fenster.
Da dies dann das Ende des Skripts ist Hier() Namespace, der für das Skript erstellt wurde, wird gelöscht und der Speicher gelöscht.
Wenn Sie die Tabelle schließen, findet sie das Literal exprA als schließendes Skript, dann versucht es, den Namen wie oben (in Lokal() , Hier() , Global() ), nur diesmal gibt es keine Hier() Namespace und es kann den Namen in keinem der drei Namespaces finden, wodurch ein Fehler ausgegeben wird.
Wenn Sie eine Variable als statischen Wert zu einem Ausdruck hinzufügen möchten, der in einem anderen Gültigkeitsbereich ausgeführt wird, verwenden Sie im Allgemeinen beides Eval( Eval Ausdr( ...; Ausdr( Name Ausdruck( val ) ); ... ) ) oder ein anderes Äquivalent.
Nach meiner persönlichen Erfahrung erstelle ich explizite Namespaces für jedes Skript (anonym) und beschränke dann manuell alle Variablen auf den jeweiligen Namespace.Ich kann diesen Namensraum dann nach Bedarf weitergeben (und natürlich lösche und schließe ich den Namensraum, wenn das Skript fertig / das Fenster geschlossen ist).
Einige Beispiele dafür, wie Ihr Skript zum Laufen gebracht werden könnte, lauten wie folgt:
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 ) ) );
) );
oder
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 ) ) );
) );
oder
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 )
)
);
) );Beachten Sie, dass viele Programmiersprachen zwar lokale Namespaces erstellen und sie mithilfe von Referenzzählern aufbewahren, bis sie nicht mehr benötigt werden (z. B. Python mit Funktionen und dergleichen), JSL dies jedoch nicht wirklich tut und es Sache des Programmierers ist, welche zu verwalten Beharrlichkeit und Zielstrebigkeit erforderlich. Der Code in der <<BEIM schließen=""> Die Nachricht wird in einem völlig anderen Kontext als das Skript ausgewertet, das sie erstellt hat, ohne dass Namen oder Bereiche verwaltet werden.</BEIM>
Hoffe, das hilft, es kann ein bisschen verwirrend sein !!
Betreff: Brauchen Sie Hilfe, um zu verstehen, wie Variablen in Ausdrücken geltenJordan, vielen Dank, es erklärt das Verhalten. Ich mag Ihren vorgeschlagenen Weg mit Namespaces, da das echte Skript viele Tabellen hat, die Variablen in ihren OnClose-Anweisungen teilen würden.
Können Sie mir helfen, den folgenden Code zu verstehen:
Local( {self = Namespace( Expr( self << Get Name ) )},
self:exprA;
Delete Namespaces( Force( 1 ), self )
)Local löst Namen in lokale Variablen auf, was bedeutet das? Warum müssen Sie einige Variablen in geschweiften Klammern definieren, was ist der Zweck? (sowohl der Scripting-Index als auch die Dokumentation sagen nicht viel darüber aus).
Betreff: Brauchen Sie Hilfe, um zu verstehen, wie Variablen in Ausdrücken geltenKurze Antwort – es verhindert, dass Namen etwas außerhalb überschreiben Lokal() Block.
Lange Antwort:
Für meine Funktionen schreibe ich sie wie folgt:
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
)
Ich verwende dann Metaprogrammierung, um zu definieren selbst und fügen Sie eine Referenz in jede Funktion ein, die sie in etwas wie Folgendes umwandelt:
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
)Dadurch entsteht etwas, das Python-Klassen sehr ähnlich ist (mein Code unterscheidet sich stark von den obigen Anweisungen, ist aber konzeptionell ähnlich).Die Sache, die ich nie passieren lassen möchte, ist, die Referenz zu haben selbst durch einen anderen Wert überschrieben werden.
Stellen Sie sich vor, dass ich in einer Funktion a habe Warte ( 1 ) aus irgendeinem Grund funktionieren, und während dieser Wartephase schließt jemand eine Tabelle, an die ein Skript angehängt ist, das neu definiert selbst -- wenn die Wait-Anweisung dann fertig ist selbst bezieht sich nun auf eine andere Variable und es entsteht Chaos.
Der Lokal() Die Funktion erstellt einen lokalen Block und alle Variablen, die im ersten Argument (der Liste) definiert sind, sind lokal für diesen Block, wie z
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;Hier definiere ich beides neu A Und B innerhalb des lokalen Blocks, aber B außerhalb des lokalen Blocks ist dabei nicht betroffen A Ist.Putten selbst als lokale Variable ist der sicherste Ansatz.
Benötigen Sie Hilfe beim Verständnis des Gültigkeitsbereichs von Variablen in Ausdrücken?Hallo alle,
Ich habe ein einfaches Beispielskript. Kann mir jemand erklären, welche Bereiche die Variablen hier haben und warum es auf die eine und nicht auf die andere Weise funktioniert?
Hier ist das erste Skript:
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;Die Idee ist, dass ich einen Tisch öffne und ihm einen Ausdruck gebe, den er zum Ausführen benötigt, wenn er geschlossen ist. Der Ausdruck wertet einige Variablen aus dem Skript aus und ändert sie (nicht in diesem Beispiel).
So wie es geschrieben ist, funktioniert es nicht – es passiert nichts, aber in meinem echten Skript heißt es nur, dass keine Referenz gefunden werden kann.
Okay, versuchen wir, ExprA global zu machen:
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;Jetzt sieht es den Ausdruck, aber es funktioniert immer noch nicht, weil es jetzt die x-Variable nicht sieht.
Ok, machen wir x auch 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;Jetzt funktioniert es:
Scriptable[]Here is variable: Variable
// Close Data Table: Big Class
Close( "Big Class" );
Die Frage: Warum funktioniert es so und nicht auf die ursprüngliche Weise? Ich dachte, es hätte funktionieren sollen.
Ich verwende in diesem Skript keine globalen Variablen. Gibt es eine andere Möglichkeit, es zum Laufen zu bringen?
Erweiterte statistische ModellierungAutomatisierung und SkripterstellungVerbraucher- und MarktforschungDatenzugriffDatenmischung und -bereinigungVersuchsplanungMassenanpassungQualitäts- und Verfahrenstechnik