ColdFusion: ¿es seguro omitir la palabra clave de variables en un CFC?
(9)
No importará especificar "variables" cuando crees la variable, porque foo se ubicará 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 de función "
doAnotherThing ("args") devuelve "Tengo una instancia privada de una variable y una función local variable ".
En un Componente ColdFusion (CFC), ¿es necesario usar nombres completamente calificados para las variables con ámbito de variables?
¿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>
Especialmente en los CFC, el alcance adecuado es importante. La "verbosidad" adicional vale la claridad. El hecho de que las variables salgan de su alcance intrínseco causará problemas graves y será muy difícil de diagnosticar.
La 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 .
La respuesta simple a su pregunta es: "NO, no es necesario"
Sin embargo, creo que las mejores prácticas sugieren que, de hecho, utilice 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, agrego un poco de verbosidad adicional a mis UDF de CFC creando una estructura local:
<cfset var local = structNew () />
Luego pongo todos mis vars locales en esa estructura y los refiero de esa manera para que mi código se vea así:
<cfset local.foo = variables.bar + 10 />
Dejando a un lado las mejores prácticas, creo que también podría depender de cómo va a acceder a su 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.
Yo diré que sí. ¿Es explícitamente necesario? Nop. ¿Puedes salirte con la tuya sin hacerlo? Por supuesto. ¿Estás pidiendo problemas? Absolutamente. Si tiene lo siguiente dentro de un cffunction:
<cfset foo = "bar" />
Eso no colocará esa variable en la función local var scope, sino que la colocará en el alcance global VARIABLES de 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 (SOLICITUD., SESIÓN., Etc.), ColdFusion ejecutará ScopeCheck () para determinar en qué ámbito se encuentra la variable. No solo Esto supone una sobrecarga innecesaria en su servidor de aplicaciones, sino que 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, alcance 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.
Aquí hay una muy buena referencia de alcance de CFC de Raymond Camden. Personalmente, prefiero hacer un ''auto'' hash para evitar toda confusión (nótese que no uso el ámbito ''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>
...
El alcance no explícito en el alcance de las variables puede funcionar, pero no es una buena idea, y sinceramente, la única razón para no hacerlo es la OMI de pereza. Si abarca todo de manera explícita 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 aparecer si no tiene un alcance explícito.
La respuesta breve a su pregunta es que no, probablemente no tendrá 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 de 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, 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>
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 haces lo siguiente dentro de una UDF:
<cfset foo = "bar" />
Luego le está diciendo a CF que ponga esa variable en el alcance var.
Para complicar un poco las cosas, puede tener problemas (los valores de las variables cambian cuando no los esperaba) cuando no está utilizando el alcance var en sus UDF en línea.
Por lo tanto, la regla general es siempre, siempre, SIEMPRE, SIEMPRE var-scope las variables internas de la función (incluidos los nombres de las consultas). Hay una herramienta llamada varScoper que lo ayudará a encontrar las variables que necesitan ser var-scoped. La última vez que lo revisé no fue perfecto, pero definitivamente es un comienzo.
Sin embargo, es una mala idea hacer referencia (mostrar / usar) variables sin un ámbito (obviamente, exceptuando las variables de ámbito var, ya que no se puede especificar el alcance para leer) en los CFC o incluso en sus páginas CFM estándar. 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: implicar el alcance de una variable (en el conjunto) no es una idea terrible (aunque normalmente lo especifico de todos modos); pero deducir el alcance de la variable (en lectura) es buscar problemas.
Después de leer sus respuestas, esto es lo que estoy pensando:
Si, 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.
De acuerdo, hay una excepción menor, como señaló Soldarnal , donde se requiere calificar una variable con ámbito de variables. Eso es si tienes una variable local de función con el mismo nombre. (Pero probablemente no deberías hacer eso de todos modos).