2008-09-12 2 views
5

Ist es in einer ColdFusion-Komponente (CFC) erforderlich, vollständig qualifizierte Namen für Variable-Scoped-Variablen zu verwenden?ColdFusion: Ist es sicher, das Variablen-Schlüsselwort in einem CFC wegzulassen?

Werde ich mich in Schwierigkeiten bringen, wenn ich diese ändern:

<cfcomponent> 
    <cfset variables.foo = "a private instance variable"> 

    <cffunction name = "doSomething"> 
     <cfset var bar = "a function local variable"> 
     <cfreturn "I have #variables.foo# and #bar#."> 
    </cffunction> 
</cfcomponent> 

dazu?

Antwort

10

Es spielt keine Rolle, "Variablen" anzugeben, wenn Sie die Variable erstellen, da foo standardmäßig im Variablenbereich platziert wird; Aber es wird wichtig sein, wenn Sie auf die Variable zugreifen.

<cfcomponent> 
    <cfset foo = "a private instance variable"> 

    <cffunction name="doSomething"> 
     <cfargument name="foo" required="yes"/> 
     <cfset var bar = "a function local variable"> 
     <cfreturn "I have #foo# and #bar#."> 
    </cffunction> 

    <cffunction name="doAnotherThing"> 
     <cfargument name="foo" required="yes"/> 
     <cfset var bar = "a function local variable"> 
     <cfreturn "I have #variables.foo# and #bar#."> 
    </cffunction> 

</cfcomponent> 

doSomething ("args") gibt "Ich habe args und eine Funktion lokale Variable"

doAnotherThing ("args") gibt „Ich habe eine private Instanz einer Variablen und eine Funktion lokale Variable. "

+0

Ja, nehmen die Argumente Vorrang vor der Instanzvariable. Damit bin ich einverstanden. Es ist konsistent mit anderen Sprachen, wo ich dieses oder self verwenden müsste, um die Instanzvariable im Gegensatz zu dem Argument zu referenzieren. –

3

Die kurze Antwort auf Ihre Frage ist, dass nein, Sie werden wahrscheinlich nicht in Schwierigkeiten geraten, dies zu tun. Außerhalb des Kontextes einer UDF (selbst noch innerhalb eines CFC) impliziert eine nicht-beschränkte set-Anweisung den Gültigkeitsbereich der Variablen.

Darüber hinaus steht in einem CFC der Gültigkeitsbereich Variablen für alle Funktionen zur Verfügung. Es ist eine Art globaler Geltungsbereich in diesem CFC - ähnlich wie im "this" - Bereich, außer dass der Gültigkeitsbereich der Variablen "privaten" Variablen ähnelt, während der Gültigkeitsbereich den öffentlichen Variablen ähnelt.

Um dies zu testen, erstellen test.cfc:

<cfcomponent> 
    <cfset foo = "bar" /> 
    <cffunction name="dumpit" output="true"> 
     <cfdump var="#variables#" label="cfc variables scope"> 
     <cfdump var="#this#" label="cfc this scope"> 
    </cffunction> 
</cfcomponent> 

und eine Seite zu testen, test.cfm:

<cfset createObject("component", "test").dumpit() /> 

Und werden die Ergebnisse sein:


Nun, um ein anderes Problem zu adressieren, sehe ich in Ihrem Beispiel Code ...

In CF haben alle benutzerdefinierten Funktionen einen speziellen nicht benannten Bereich, der gemeinhin als "var" Bereich bezeichnet wird. Wenn Sie die folgenden Aktionen in einem UDF:

<cfset foo = "bar" /> 

Dann CF sagen Sie diese Variable in den var Rahmen zu setzen.

Um ein wenig Verbindung Dinge, Sie Probleme (Variablenwerte zu ändern, wenn Sie sie nicht erwartet hatten) laufen können, wenn Sie nicht mit dem var Umfang im Inline-UDFs sind.

So ist die Faustregel immer, immer, immer, IMMER var-scope Ihre Funktion internen Variablen (einschließlich Abfrage-Namen).Es gibt ein Tool mit der Bezeichnung varScoper, das Sie beim Auffinden von Variablen unterstützt, die var-scoped sein müssen. Zuletzt habe ich überprüft, dass es nicht perfekt war, aber es ist definitiv ein Anfang.

Es ist jedoch eine schlecht Idee (Anzeige/Nutzung) Variablen zu verweisen, ohne Rahmen (natürlich var-scoped Variablen ausgenommen, da Sie nicht den Bereich angeben können von lesen) in FCKW oder sogar auf Ihrem Standard-CFM-Seiten. Ab CF7 gab es 9 Bereiche, die in einer bestimmten Reihenfolge überprüft wurden, wenn Sie eine Variable ohne Angabe des Bereichs lesen, erste Übereinstimmung gewinnt. Mit CF8 könnte es mehr Bereiche in dieser Liste geben, die ich nicht überprüft habe. Wenn Sie das tun, riskieren Sie, einen Wert von einem Bereich zu erhalten, wenn Sie es von einem anderen erwarten; Das ist ein Albtraum zu debuggen ... Ich versichere Ihnen. ;)

Also kurz: implizieren der Umfang einer Variablen (am Set) ist keine schreckliche Idee (obwohl ich es normalerweise sowieso angeben); aber Schlussfolgerung Variable Umfang (auf lesen) fragt nach Ärger.

+0

Meinten Sie ''? –

+0

Und mein Beispielcode verwendet das Schlüsselwort var. Also, ähm, ich bin verwirrt. :-) –

+0

Nein, ich habe absichtlich die "var" in dieser Aussage weggelassen; Es ist ein Beispiel für schlechte Praktiken. Ihr Beispiel verwendet var, aber Sie entfernen "Variablen". was ich sage ist eine schlechte Idee. Siehe die Antwort von Dan Wilson bezüglich Wartbarkeit. –

0

Nach Ihre Antworten hier zu lesen, was ich denke:

Ja, es ist sicher. Im Allgemeinen ist es nicht notwendig oder sinnvoll, den Variablenbereich explizit anzugeben. Es fügt nur einer bereits ausführlichen Sprache Unordnung hinzu.

Zugegeben, es gibt eine kleine Ausnahme, wie Soldarnal hingewiesen, wo die Qualifizierung einer Variable-Bereich Variable erforderlich ist. Das heißt, wenn Sie eine Funktion lokale Variable mit dem gleichen Namen haben. (Man sollte aber wahrscheinlich, dass ohnehin nicht tun.)

1

Die einfache Antwort auf Ihre Frage ist: „Nein, es ist nicht notwendig,“

Aber ich denke, Best Practices würde vorschlagen, dass Sie das tun, In der Tat, verwenden Sie die Variable Identifikator beim Zugriff auf diese Variablen. Meiner Meinung nach wird jeder, der in der Zukunft auf Ihren Code stößt und in der Mitte einer Funktion steht, sofort das Scoping der Variablen kennen, ohne die Funktionen der lokalen Funktionen oben scannen zu müssen.

In der Tat, füge ich ein wenig mehr Ausführlichkeit zu meinem CFC UDF durch eine lokale Struktur zu schaffen:

< cfset var local = StructNew()/>

Dann legte ich meine alle lokalen Vars, dass Struktur und sie auf diese Weise verweisen, so wird mein Code in etwa so aussehen:

< cfset local.foo = variables.bar + 10/>

5

Besonders in C FCs, richtiges Scoping ist wichtig. Die zusätzliche "Ausführlichkeit" ist die Klarheit wert. Wenn Variablen aus ihrem indizierten Bereich herausfallen, führt dies zu schwerwiegenden Problemen und ist sehr schwer zu diagnostizieren.

Ausführlichkeit ist nicht immer eine schlechte Sache. Wir benennen unsere Funktionen und Methoden auf beschreibende Weise wie getAuthenticatedUser() statt gau(). Datenbankspalten und -tabellen sind am besten beschreibend wie EmployeePayroll und nicht empprl. Daher ist es vielleicht "einfacher", kurz zu sein, wenn Ihr Kurzzeitgedächtnis voller Projektdetails ist, aber beschreibend zu sein, zeigt Ihre Absicht und ist während der Wartungsphase einer Anwendung hilfreich, lange nachdem Ihr Kurzzeitgedächtnis mit anderen Dingen gefüllt wurde .

0

Best Practices zur Seite, glaube ich es auch davon abhängen könnte, wie Ihr Ihr FCKWs zugreifen werde ich habe keine Probleme hatte sie aus verlassen, wenn Objekte zu schaffen und sie von Coldfusion zugreifen. Ich denke jedoch, dass es erforderlich sein könnte, wenn Sie auf sie zugreifen und/oder sie remote über das ActionScript in flex/flash abbilden.

6

Ich werde sagen Ja. Ist es explizit notwendig? Nee. Kannst du damit davonkommen, es nicht zu tun? Sicher. Fragen Sie nach Ärger? Absolut. Wenn Sie die folgenden in einem cffunction haben:

<cfset foo = "bar" /> 

das nicht, dass Variable in der Funktion lokal var Umfang stattfinden wird, wird es in den globalen Variablen Umfang des CFC platzieren, was bedeutet, dass es zu jeder Methode, die verfügbar ist FCKW. Es gibt Zeiten, in denen du das vielleicht willst, aber meistens fragst du nach einer Wettlaufsituation.

Wenn eine Variable vom Server gelesen wird und diese Variable nicht explizit als Teil eines Bereichs deklariert wird (REQUEST., SESSION., Usw.), führt ColdFusion mit ScopeCheck() den Gültigkeitsbereich der Variablen aus Dies bedeutet nicht nur einen unnötigen Overhead für Ihren Anwendungsserver, sondern auch die Fähigkeit zum Hijacking, wobei Ihre Variable in einem Bereich liegt, während ScopeCheck() eine Variable mit dem gleichen Namen in der Rangordnung gefunden hat.

immer, immer, immer, Umfang aller Variablen. Egal wie trivial. Auch Dinge wie Abfragenamen und Schleifenindizes. Rette dich selbst und diejenigen, die hinter dir kommen, vor dem Schmerz.

0

Hier ist eine sehr gute CFC scope reference von Raymond Camden. Ich persönlich lieber ein ‚Selbst‘ Hash machen alle Verwirrung zu vermeiden (merke ich nicht den ‚Variablen‘ Umfang in den Funktionen verwenden Sie):

<cfcomponent> 
    <cfset variables.self = structNew()> 
    <cfscript> 
    structInsert(variables.self, <key>, <value>); 
    ... 
    </cfscript> 

    <cffunction name="foo"> 
    self.<key> = <value> 
    <cfreturn self.<key> /> 
    </cffunction> 

    ... 
2

nicht explizit in den Variablen Scoping Umfang arbeiten kann, aber es ist keine gute Idee, und ehrlich gesagt ist der einzige Grund, nicht ist aus Faulheit IMO. Wenn Sie explizit alles in Betracht ziehen 1) vermeiden Sie potentielle Probleme, und 2) es macht den Code einfacher zu lesen, da es keine Frage gibt, in welchem ​​Bereich Dinge sind.

Für mich macht es den Code nicht ausführlicher (und sicherlich nicht unnötig ausführlich) - es ist tatsächlich einfacher zu lesen, vermeidet Verwirrung und vermeidet seltsame Nebenwirkungen, die auftreten können, wenn Sie nicht explizit Umfang.

+0

Ich stimme völlig zu! Ich wünschte, ich hätte diesen Rat schon vor Jahren gehört. Jetzt habe ich alles im Blick. Ich meine alles! Mein Hund und meine Katze sind sogar im Visier: ANIMAL.Dog.Rover und ANIMAL.Cat.Snickers. –

Verwandte Themen