Wie lautet die Bewertungsreihenfolge des Bereichs in ColdFusion beim Festlegen einer Variablen?

8

Die Reihenfolge der Scope-Evaluierung ist bekannt / dokumentiert, wenn Variablen verwendet . Beim Festlegen einer Variablen kann ich jedoch keine Informationen über die Reihenfolge der Gültigkeitsbereiche des Bereichs finden.

Man könnte annehmen, dass es die gleiche Liste ist, aber es scheint einige Vorbehalte zu geben, wie hier gezeigt:

%Vor%

Der obige Code versucht, einen Variablennamen wiederzuverwenden, der nicht verwendet werden sollte, aber auf eine unerwartete Weise fehlschlägt.

Da sich die cfset s in einer Abfrageschleife befinden, sollte für beide der Punkt 4 der Scope-Evaluierungsreihenfolge verwendet werden. Stattdessen wird Next als Variables.Next (Element 6) ausgewertet, und dann wird Next.id als Variables.qryChain.next.id (Element 4) ausgewertet und schlägt fehl.

Ist das irgendwo dokumentiert? Sind es einfach die Punkte 1-6 der obigen "using" -Liste mit ein paar Vorbehalten? Sind diese Vorbehalte Absicht oder Fehler? Welche anderen Vorbehalte gibt es?

    
nosilleg 10.02.2012, 16:10
quelle

3 Antworten

3

Scope-Evaluierung während der Zuweisung

Beim Erstellen von Variablen in ColdFusion sind mir zwei verschiedene Methoden der Bereichsevaluierung bekannt. Ich habe nicht jede mögliche Instanz getestet, aber so sollte es funktionieren.

Die erste Instanz verwendet die vollständige Liste der Bereiche in nicht skalierten Variablen auswerten . Dies wird von cfparam beim Erstellen von Variablen verwendet. Wenn ColdFusion keine Variable mit dem angegebenen Namen findet, wird sie im Bereich Variablen erstellt.

Die zweite Instanz verwendet die ersten 6 Bereiche in nicht skalierten Variablen bewerten und Wenn dies nicht erfolgreich ist, wird die Variable auch im Bereich "Variablen" erstellt. Dies wird von cfset und anderen Tags verwendet, die Variablen erstellen, z. B. cfhttp mit dem Attribut result und cfsavecontent s variable .

Wie Sie beobachtet haben, gibt es das seltsame "manchmal ignoriere" Problem mit dem Abfragebereich. Ich würde dies als einen Fehler klassifizieren, aber jemand kann vielleicht noch einen Grund angeben, warum die Ausnahme gemacht werden muss.

Hochziehen

Obwohl ColdFusion JavaScript auf viele Arten kopiert hat (speziell cfscript ) gibt es eine subtile Abweichung, die ich nicht dokumentiert gesehen habe. In Bezug auf Funktionen (sowohl Skript als auch Tag) verwendet JavaScript das Hochziehen, während ColdFusion das nicht tut.

Beim Hochladen wird die Deklaration einer Variablen automatisch an den Anfang der Funktion verschoben, während die Code-Platzierung der Zuweisung der Variablen beibehalten wird. Das bedeutet, dass sich der Gültigkeitsbereich einer Variablen in JavaScript nicht ändert, aber in ColdFusion.

Vor CF9 musste das var-Schlüsselwort oben in der Funktion verwendet werden, was die Notwendigkeit des Hochziehens im Wesentlichen zunichte machte. Dies unterscheidet sich von JavaScript, wo var überall in einer Funktion verwendet werden kann und das Heben verwendet. Mit CF9 übernahm ColdFusion die "declare anywhere" -Philosophie, vernachlässigte jedoch die Einführung von Hubwerken.

In beiden folgenden Beispielen würde JavaScript nur mit einem einzelnen Bereich arbeiten, wobei x lokale Funktion ist.

%Vor%

Im Vergleich zu:

%Vor%

Um die möglichen Fallstricke zu vermeiden, die durch das fehlende Hochziehen verursacht werden, können Sie entweder var nur am Anfang der Funktion verwenden, oder Dinge, die vor CF9 so viele haben, und eine var-Struktur am Anfang der Funktion und des Präfix deklarieren alle Variablen mit diesem (denk daran, es nicht lokal zu nennen). z.B.

%Vor%

var gegen local

In% var scheint ein Bürger zweiter Klasse für den Bereich local zu sein. Wenn Sie versuchen, eine lokale Variable mithilfe von var auf denselben Namen als Argument festzulegen, erhalten Sie die Fehlermeldung Verwenden Sie local, um eine lokale Variable mit demselben Namen zu definieren. trotz var und local soll gleichwertig sein.

Mehr

Es kann weitere Vorbehalte und Fehler geben, mir sind jedoch keine dokumentierten Fälle bekannt.

    
nosilleg 09.03.2012, 10:49
quelle
5

Ich glaube, ich verstehe, was hier vor sich geht. Das Verhalten, das Sie sehen, stammt aus der Scopesuche beim Zugriff auf Variablen, um sie festzulegen. Wenn Sie eine Variable ohne Bereichsdefinierung festlegen, durchsucht ColdFusion die Bereiche, um festzustellen, ob diese Variable an einer anderen Stelle existiert. Ist dies der Fall, wird sie dort festgelegt.

In Ihrem ersten Beispiel:

%Vor%

Wenn Sie Ihre "Next" -Variable erstellen, wird diese Variable tatsächlich in den VARIABLES-Bereich platziert. Dies können Sie nachweisen, wenn Sie den Variablenbereich zu irgendeinem Zeitpunkt während des Schleifenprozesses ausgeben. Sie werden eine "Nächste Variable" mit einer leeren Struktur sehen.

Das Problem ist in der nächsten Zeile. Wenn Sie versuchen, auf die Variable Next zuzugreifen, um einen neuen Schlüssel darauf festzulegen, sucht ColdFusion die Variable Next, die zuerst im Abfrageergebnis vorhanden ist, weil während der Abfrage eine Abfrage den Gültigkeitsbereich abfragt (nicht wirklich ein Bereich, aber wie in Dieser Fall hat eine höhere Priorität als der Gültigkeitsbereich der Variablen. Diese Variable enthält keine Struktur, daher erhalten Sie eine Fehlermeldung darüber, wie Sie darauf verweisen.

Scopesuche findet statt, aber es ist nicht wirklich während der Einstellung, es ist während des Zugriffs, um zu setzen.

Hier ist ein Arbeitsbeispiel, um dies zu demonstrieren.

%Vor%

In diesem Beispiel zeige ich, dass nachdem Sie die nächste Variable erstellt haben, diese im Gültigkeitsbereich der Variablen vorhanden ist, aber wenn Sie sofort versuchen, einen Schlüssel ohne Scoping für diesen Zugriff festzulegen, erhalten Sie stattdessen die NEXT-Variable aus dem aktuellen Datensatz in der Abfrage. Dies geschieht nur, weil die Abfrage einen Datensatz mit einem Spaltennamen enthält, der zufällig mit der Variablen übereinstimmt, die Sie verwenden möchten.

Warum versucht ColdFusion nicht, StructNew () in den Abfrage-Bereich (Pseudo-Bereich) zu setzen? Die Abfrage kann nicht mithilfe der Punktnotation manipuliert werden. Auch hier handelt es sich nicht wirklich um einen Bereich. In diesem Sinne ist es schreibgeschützt und wird übersprungen Um einen Abfrageergebnissatz in CF zu bearbeiten, müssen Sie den query functionsVARIABLES-Bereich verwenden. Da nicht verkoppelte Variablen immer in den VARIABLES-Bereich gestellt werden. In der Zeile, in der Sie versuchen, die ID zu setzen, gibt es jedoch eine andere Phase im Hintergrund, in der zuerst auf die Variable in einer Lesekapazität zugegriffen werden muss und dann versucht wird, die Menge auszuführen. In diesem Fall findet es die NEXT-Variable in der Abfrage, da die Bereichsuche zuerst stattfindet, um zu ermitteln, ob NEXT den Schlüssel in das Feld setup setzt, und wenn Sie dann versuchen, etwas darauf zu setzen, schlägt es fehl.

Was Ihr zweites Beispiel betrifft, ist dies ein erwartetes Verhalten, das leicht erklärt werden kann.

Im ersten Beispiel ändern Sie Ihre Variable (die sie in den lokalen Bereich legt). Sie legen dann den Wert dieser Variablen fest. Wenn Sie einen Wert für eine Variable festlegen (ohne diese zu definieren), prüft ColdFusion, ob diese Variable bereits vorhanden ist (also eine Bereichsuche durchführt, wiederum greift sie auf diesen Punkt zu, nicht auf die Einstellung) und findet sie im lokalen Bereich und legen Sie den Wert dort fest. Danach legen Sie den Wert erneut fest, und zwar diesmal, indem Sie den Wert korrekt festlegen, sodass keine Suche durchgeführt wird.

Im zweiten Beispiel wird die Variable bei der ersten Verwendung nicht variiert, sie existiert nirgendwo und wird daher auf den Variablenbereich festgelegt. Wenn es bereits im lokalen Bereich vorhanden wäre, hätte ColdFusion es gefunden und dort festgelegt (wie in Ihrem ersten Beispiel), aber da es nicht existierte und es nicht var'd war, wurde es auf den Gültigkeitsbereich der Variablen gesetzt.

Schließlich, in Ihrem letzten Beispiel, legen Sie Ihre Variable explizit fest und werden daher im lokalen Bereich festgelegt. Sie legen es dann erneut fest, ohne es zu definieren. ColdFusion findet es im lokalen Bereich und überschreibt es.

Die Moral der Geschichte ist, Umfang Ihre Variablen. Es ist wichtig, das erwartete Verhalten zu erhalten. Scope-Search war nie eine gute Idee, aber leider ist es hier zu bleiben. Ich sehe hier nichts, was ich einen Fehler oder sogar unvorhersehbares Verhalten nennen würde, wenn Sie die Funktionsweise der Scope-Suche verstehen.

    
Jason Dean 10.02.2012 17:34
quelle
0

Sie erhalten diesen Fehler vermutlich (da es sich um den Fehler handelt, den ich erhalten habe):

%Vor%

Dies liegt daran, dass der Abfragebereich bei der Auswertung einer bereichslosen Variablen Vorrang vor dem Gültigkeitsbereich der Variablen hat, wenn Sie sich innerhalb eines cfloop für eine Abfrage befinden. Wenn Sie jedoch bereichslose Variablen zuweisen (entweder in einem cfloop-Abfragekontext oder nicht), verwenden Sie den variables -Bereich. Also wenn Sie

zuweisen %Vor%

Sie setzen die Variable "Next" auf den Bereich variables. . Wenn Sie jedoch versuchen, Next auszuwerten (indem Sie auf seinen Schlüssel .id verweisen), wie folgt:

%Vor%

Jetzt erhalten Sie Next aus dem Abfragebereich (und da Next im Abfragebereich keine Struktur ist, erhalten Sie einen Fehler).

Um zu versuchen, Ihre Hauptfrage zu beantworten - wenn Sie eine Variable zuweisen, für die kein Bereich angegeben wurde, wird CF die Variable in den Bereich variables setzen. Wenn Sie versuchen, eine Variable ohne angegebenen Bereich auszuwerten, wird der normale Bereich- verwendet. Vorrangregeln , um eine Übereinstimmung zu finden (in diesem Fall eine im Bereich query zu finden).

    
Jake Feasel 10.02.2012 17:31
quelle

Tags und Links