Domanda

In un componente ColdFusion (CFC), è necessario utilizzare nomi completi per le variabili con ambito variabile?

Mi metterò nei guai se cambio questo:

<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>

a questa?

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

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

Soluzione

Non avrà importanza specificare "variabili" quando crei la variabile, perché foo verrà inserito nell'ambito delle variabili per impostazione predefinita;ma avrà importanza quando accedi alla variabile.

<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>

faiQualcosa("args") restituisce "Ho arg e un variabile locale della funzione"

doAnotherThing("args") restituisce "Ho un'istanza privata di una variabile e un variabile locale della funzione."

Altri suggerimenti

Dirò di sì.È esplicitamente necessario?No.Puoi farla franca se non lo fai?Sicuro.Stai cercando guai?Assolutamente.Se hai quanto segue all'interno di una funzione cf:

<cfset foo = "bar" />

Ciò non posizionerà quella variabile nell'ambito var locale della funzione, la inserirà nell'ambito globale VARIABLES di CFC, il che significa che è disponibile per ogni metodo di quel CFC.Ci sono momenti in cui potresti volerlo fare, ma la maggior parte delle volte ti verrà richiesta una condizione di gara.

Quando una variabile viene letta dal server, se tale variabile non è dichiarata esplicitamente come parte di un ambito (REQUEST., SESSION., ecc.), ColdFusion eseguirà ScopeCheck() per determinare in quale ambito si trova la variabile.Questo non solo impone un sovraccarico non necessario sul server delle applicazioni, ma introduce anche la possibilità di dirottamento, per cui la variabile è in un ambito, ma ScopeCheck() ha trovato una variabile con lo stesso nome più in alto nell'ordine di precedenza.

Sempre, sempre, SEMPRE, ambito di tutte le variabili.Non importa quanto banale.Anche cose come i nomi delle query e gli indici in loop.Salva te stesso e chi ti segue dal dolore.

Soprattutto nei CFC è importante un’adeguata definizione dell’ambito.La "verbosità" extra vale la chiarezza.Il fatto che le variabili escano dall'ambito previsto causerà gravi problemi e sarà molto difficile da diagnosticare.

La verbosità non è sempre una cosa negativa.Diamo nomi alle nostre funzioni e metodi in modo descrittivo come getAuthenticatedUser(), anziché gau().È meglio lasciare le colonne e le tabelle del database descrittive come EmployeePayroll anziché empprl.Pertanto, essere concisi potrebbe essere "più facile" quando la memoria a breve termine è piena dei dettagli del progetto, ma essere descrittivi mostra le tue intenzioni ed è utile durante la fase di manutenzione di un'applicazione, molto tempo dopo che la memoria a breve termine è stata riempita con altre cose. .

La risposta breve alla tua domanda è no, probabilmente non avrai problemi nel tentativo di farlo.Al di fuori del contesto di una UDF (anche all'interno di un CFC), un'istruzione set senza ambito implica l'ambito delle variabili.

Inoltre, in un CFC, l'ambito Variabili è disponibile per tutte le sue funzioni;è una sorta di ambito globale all'interno di quel CFC - simile all'ambito "questo", tranne per il fatto che l'ambito delle variabili è simile alle variabili "private", mentre l'ambito this è simile alle variabili pubbliche.

Per testarlo, crea 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>

e una pagina per testarlo, test.cfm:

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

E i risultati saranno:


Ora, per risolvere un altro problema che vedo nel tuo codice di esempio...

In CF, tutte le funzioni definite dall'utente hanno uno speciale ambito senza nome comunemente denominato ambito "var".Se esegui le seguenti operazioni all'interno di una UDF:

<cfset foo = "bar" />

Quindi stai dicendo a CF di inserire quella variabile nell'ambito var.

Per complicare un po' le cose, puoi incorrere in problemi (i valori delle variabili cambiano quando non te lo aspettavi) quando lo sei non utilizzando l'ambito var nelle UDF in linea.

Quindi la regola pratica è sempre, sempre, SEMPRE, SEMPRE var-scope le variabili interne alla funzione (inclusi i nomi delle query).C'è uno strumento chiamato varScoper che ti aiuterà a trovare le variabili che devono essere sottoposte a var-scope.L'ultima volta che ho controllato non era perfetto, ma è sicuramente un inizio.

Tuttavia, è un Cattivo idea di fare riferimento (visualizzare/utilizzare) variabili senza ambito (ovviamente ad eccezione delle variabili con ambito var, poiché non è possibile specificare l'ambito da cui leggere) nei CFC o anche nelle pagine CFM standard.A partire da CF7, c'erano 9 ambiti che venivano controllati in un ordine specifico quando si leggeva una variabile senza specificare l'ambito, vince la prima corrispondenza.Con CF8 potrebbero esserci più ambiti in quell'elenco, non ho controllato.Quando lo fai, corri il rischio di ottenere un valore da un ambito quando te lo aspetti da un altro;che è un incubo da eseguire il debug...Ti assicuro.;)

Quindi in breve: implicando l'ambito di una variabile (sul set) non è un'idea terribile (anche se di solito lo specifico comunque);Ma inferendo l'ambito della variabile (in lettura) è in cerca di problemi.

Non definire esplicitamente l'ambito delle variabili può funzionare, ma non è una buona idea e, onestamente, è l'unica ragione non è per pigrizia, IMO.Se definisci esplicitamente l'ambito di tutto 1) eviti potenziali problemi e 2) rendi il codice più facile da leggere perché non c'è dubbio in quale ambito si trovino le cose.

Per me questo non rende il codice più prolisso (e certamente non inutilmente prolisso): in realtà è più facile da leggere, evita confusione ed evita strani effetti collaterali che potrebbero verificarsi se non si applica esplicitamente l'ambito.

La risposta semplice alla tua domanda è:"NO, non è necessario"

Tuttavia, penso che le migliori pratiche suggerirebbero di utilizzare, in effetti, l'identificatore delle variabili quando si accede a tali variabili.A mio parere, chiunque si imbatterà nel tuo codice in futuro e sta guardando nel mezzo di una funzione, conoscerà immediatamente l'ambito della variabile senza dover scansionare la parte superiore della funzione nelle funzioni locali.

In effetti, aggiungo un po' di verbosità extra alle mie UDF CFC creando una struttura locale:

<cfset var local = structNew() />

Quindi inserisco tutte le mie variabili locali in quella struttura e faccio riferimento a loro in questo modo in modo che il mio codice assomigli a questo:

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

Dopo aver letto le vostre risposte ecco cosa sto pensando:

Sì, è sicuro.In generale, non è necessario né utile specificare esplicitamente l'ambito delle variabili.Aggiunge solo disordine a un linguaggio già prolisso.

Certo, c'è una piccola eccezione, come Soldarnal sottolineato, dove è richiesta la qualificazione di una variabile con ambito variabile.Questo se hai una variabile locale di funzione con lo stesso nome.(Ma probabilmente non dovresti farlo comunque.)

Migliori pratiche a parte, credo che potrebbe anche dipendere da come accederai ai tuoi cfc, non ho avuto problemi a lasciarli fuori durante la creazione di oggetti e l'accesso ad essi da Coldfusion.Tuttavia penso che potrebbe essere necessario quando si accede e/o si mappano da remoto tramite ActionScript in Flex/Flash.

Ecco un ottimo Riferimento all'ambito CFC di Raymond Camden.Personalmente, preferisco creare un hash 'self' per evitare ogni confusione (nota che non utilizzo l'ambito 'variables' nelle funzioni):

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

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

  ...
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top