2008-09-12 12 views
5

En un Componente ColdFusion (CFC), ¿es necesario utilizar nombres totalmente calificados para las variables con ámbito de variables?ColdFusion: ¿Es seguro omitir la palabra clave de variables en un CFC?

¿Voy a meterme en problemas si cambio esto:

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

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

Respuesta

10

No va a importar especificar "variables" cuando crea la variable, porque foo se colocará en el ámbito de las variables de forma predeterminada; pero importará cuando acceda a la variable.

<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") devuelve "Tengo args y una variable local función"

doAnotherThing ("args") devuelve "Tengo una instancia privada de una variable y una variable local de función . "

+0

Sí, los argumentos tienen prioridad sobre la variable de instancia. Estoy bien con eso. Es coherente con otros lenguajes, donde tendría que usar esto o uno mismo para hacer referencia a la variable de instancia en lugar de al argumento. –

3

La respuesta breve a su pregunta es que no, probablemente no tenga problemas para intentar hacer eso. Fuera del contexto de una UDF (incluso dentro de una CFC), una declaración de conjunto sin ámbito implica el ámbito de las variables.

Además, en un CFC, el alcance Variables está disponible para todas sus funciones; es una especie de alcance global dentro de CFC, similar al alcance "this", excepto que el alcance de las variables es similar a las variables "privadas", mientras que este alcance es similar a las variables públicas.

Para probar esto, cree 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> 

y una página para probarlo, test.cfm:

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

Y los resultados serán:


Ahora, para abordar otro problema que veo en su código de ejemplo ...

En CF, todas las funciones definidas por el usuario tienen un alcance especial sin nombre, comúnmente denominado alcance "var". Si lo hace la siguiente dentro de una UDF:

<cfset foo = "bar" /> 

Entonces le están diciendo CF para poner esa variable en el ámbito var.

Para compuesto un poco las cosas, puede tener problemas (valores de las variables que cambian cuando no se esperaba a) cuando se está no usando el alcance var en las UDF en línea.

Así que la regla de oro es para siempre, siempre, siempre, SIEMPRE var de alcance variables de función interna (incluyendo nombres de consulta).Hay una herramienta llamada varScoper que lo ayudará a encontrar las variables que deben ser var-scoped. La última vez que lo revisé no fue perfecto, pero definitivamente es un comienzo.

Sin embargo, es una mala ideahacer referencia a las variables (pantalla/uso), sin un endoscopio (obviamente con excepción de las variables de ámbito de var, como no se puede especificar el alcance de leer desde) en CFC o incluso en su páginas estándar de CFM. A partir de CF7, hubo 9 ámbitos que se verificaron en un orden específico cuando lee una variable sin especificar el alcance, la primera coincidencia gana. Con CF8, podría haber más ámbitos en esa lista, no he verificado. Cuando hace esto, corre el riesgo de obtener un valor de un ámbito cuando lo está esperando de otro; que es una pesadilla para depurar ... te lo aseguro. ;)

En resumen: implicando el alcance de una variable (en el conjunto) no es una idea terrible (aunque generalmente lo especifico de todos modos); pero inferir el alcance de la variable (en lectura) está buscando problemas.

+0

Quizás quiso decir ''? –

+0

Y mi código de ejemplo usa la palabra clave var. Entonces, um, estoy confundido. :-) –

+0

No, dejé intencionalmente la "var" en esa declaración; es un ejemplo de mala práctica. Su ejemplo utiliza var, pero elimina "variables". que es lo que digo es una mala idea. Vea la respuesta de Dan Wilson con respecto al mantenimiento. –

0

Después de leer sus respuestas aquí es lo que estoy pensando:

Sí, es seguro. En general, no es necesario ni útil especificar explícitamente el alcance de las variables. Simplemente agrega desorden a un lenguaje ya prolijo.

Concedido, hay una excepción menor, como Soldarnal señalado, donde se requiere calificar una variable con ámbito de variables. Eso es si tienes una variable local de función con el mismo nombre. (Sin embargo, es probable que no debe hacer eso de todos modos.)

1

La simple respuesta a su pregunta es: "NO, no es necesario"

Sin embargo, creo que las mejores prácticas sugieren que lo hace, de hecho, use el identificador de variables al acceder a esas variables. En mi opinión, cualquier persona que encuentre su código en el futuro y esté mirando en el medio de una función, sabrá instantáneamente el alcance de la variable sin tener que escanear la parte superior de la función con las funciones locales.

De hecho, añadir un poco de nivel de detalle extra para mis UDF CFC mediante la creación de una estructura local de:

< cfset var = structNew()/>

entonces puse todas mis VARs locales en ese estructura y hacen referencia a ellos de esa manera por lo que mi código se verá algo como esto:

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

5

Especialmente en C FC, el alcance adecuado es importante. La "verbosidad" adicional vale la claridad. Tener variables que se salgan de su alcance intrínseco causará problemas graves y será muy difícil de diagnosticar.

Verbosidad no siempre es algo malo. Nombramos nuestras funciones y métodos en formas descriptivas como getAuthenticatedUser(), en lugar de gau(). Las columnas y tablas de la base de datos se deben dejar descriptivas como EmployeePayroll en lugar de empprl. Por lo tanto, ser cortante puede ser 'más fácil' cuando su memoria a corto plazo está llena de detalles del proyecto, pero ser descriptivo muestra su intención y es útil durante la fase de mantenimiento de una aplicación, mucho después de que su memoria a corto plazo se haya llenado con otras cosas .

0

Dejando a un lado las mejores prácticas, creo que también podría depender de cómo va a acceder a las cfc, no he tenido problemas para omitirlas al crear objetos y acceder a ellos desde coldfusion. Sin embargo, creo que podría ser necesario al acceder y/o mapear de forma remota a través de actionscript en flex/flash.

6

Voy a decir que sí. ¿Es explícitamente necesario? Nop. ¿Puedes salirte con la tuya sin hacerlo? Por supuesto. ¿Estás pidiendo problemas? Absolutamente. Si has lo siguiente dentro de un cffunction:

<cfset foo = "bar" /> 

que no va a colocar esa variable en el ámbito var la función, que lo colocará en su alcance variables globales de la CFC, lo que significa que está disponible para todos los métodos de ese CFC. Hay momentos en que puede querer hacer esto, pero la mayoría de las veces pediría una condición de carrera.

Cuando el servidor lee cualquier variable, si esa variable no se declara explícitamente como parte de un ámbito (SOLICIT., SESIÓN., Etc.), ColdFusion ejecutará ScopeCheck() para determinar qué ámbito es la variable in. Esto no solo genera una sobrecarga innecesaria en su servidor de aplicaciones, también introduce la posibilidad de secuestro, por lo que su variable está en un ámbito, pero ScopeCheck() ha encontrado una variable del mismo nombre más alta en el orden de precedencia.

Siempre, siempre, SIEMPRE, el alcance de todas las variables. No importa cuán trivial. Incluso cosas como nombres de consultas e índices de bucle. Sálvate a ti mismo, y a aquellos que vienen detrás de ti, del dolor.

0

Aquí hay una muy buena CFC scope reference de Raymond Camden. Personalmente, prefiero hacer un hash 'auto' para evitar toda confusión (nótese que no uso el alcance 'variables' en las funciones):

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

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

    ... 
2

No determinación del alcance de manera explícita en las variables de alcance podría funcionar, pero no es una buena idea, y sinceramente, la única razón por la que no es está fuera de la pereza IMO. Si explicitamente abarca todo 1) evita problemas potenciales, y 2) hace que el código sea más fácil de leer porque no hay duda en qué ámbito están las cosas.

Para mí no hace que el código sea más detallado (y ciertamente no innecesariamente detallado) - en realidad es más fácil de leer, evita confusiones y evita los extraños efectos secundarios que pueden surgir si no tiene un alcance explícito.

+0

¡TOTALMENTE estoy de acuerdo! Ojalá hubiera seguido este consejo hace años. Ahora, alcanzo todo. Quiero decir todo! Mi perro y mi gato incluso tienen alcance: ANIMAL.Dog.Rover y ANIMAL.Cat.Snickers. –

Cuestiones relacionadas