Pregunta

En un componente ColdFusion (CFC), ¿es necesario utilizar nombres completos para variables con ámbito de variables?

¿Me voy a meter 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>
¿Fue útil?

Solución

No importará especificar "variables" cuando cree la variable, porque foo se colocará en el alcance de las variables de forma predeterminada;pero importará cuando accedas 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 argumentos y un función variable local"

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

Otros consejos

Diré que sí.¿Es explícitamente necesario?No.¿Puedes salirte con la tuya si no lo haces?Seguro.¿Estás buscando problemas?Absolutamente.Si tiene lo siguiente dentro de una función cf:

<cfset foo = "bar" />

Eso no colocará esa variable en el alcance var local de la función, la colocará en el alcance global VARIABLES del CFC, lo que significa que está disponible para todos los métodos de ese CFC.Hay ocasiones en las que es posible que quieras hacer esto, pero la mayoría de las veces estarás solicitando una condición de carrera.

Cuando el servidor lee cualquier variable, si esa variable no está declarada explícitamente como parte de un alcance (REQUEST., SESSION., etc.), ColdFusion ejecutará ScopeCheck() para determinar en qué alcance se encuentra la variable.Esto no solo genera una sobrecarga innecesaria en su servidor de aplicaciones, sino que también introduce la capacidad de secuestro, por lo que su variable está en un alcance, pero ScopeCheck() ha encontrado una variable con el mismo nombre más arriba en el orden de precedencia.

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

Especialmente en el caso de los CFC, es importante establecer un alcance adecuado.La "verbosidad" adicional vale la pena por la claridad.Que las variables se salgan de su alcance previsto causará problemas graves y muy difíciles de diagnosticar.

La verbosidad no siempre es mala.Nombramos nuestras funciones y métodos de manera descriptiva como getAuthenticatedUser(), en lugar de gau().Es mejor dejar las columnas y tablas de la base de datos como descriptivas, como EmployeePayroll en lugar de empprl.Por lo tanto, ser conciso 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 corta a su pregunta es que no, probablemente no tendrá problemas al intentar hacerlo.Fuera del contexto de una UDF (incluso dentro de un CFC), una declaración de conjunto sin alcance implica el alcance de las variables.

Además, en un CFC, el ámbito de Variables está disponible para todas sus funciones;es una especie de alcance global dentro de ese CFC, similar al alcance "este", 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 conocido como alcance "var".Si hace lo siguiente dentro de una UDF:

<cfset foo = "bar" />

Entonces le estás diciendo a CF que coloque esa variable en el alcance var.

Para complicar un poco las cosas, puedes encontrarte con problemas (los valores de las variables cambian cuando no esperabas que lo hicieran) cuando estás no utilizando el alcance var en sus UDF en línea.

Entonces la regla general es siempre, Siempre, SIEMPRE, SIEMPRE var-scope las variables internas de su función (incluidos los nombres de las consultas).Hay una herramienta llamada varScoper que le ayudará a encontrar variables que deban tener un alcance variable.La última vez que lo comprobé no era perfecto, pero definitivamente es un comienzo.

Sin embargo, es un malo Es una idea hacer referencia (mostrar/usar) variables sin alcance (obviamente con excepción de las variables con alcance var, ya que no se puede especificar el alcance para leer) en CFC o incluso en sus páginas CFM estándar.A partir de CF7, había 9 ámbitos que se verificaban en un orden específico cuando se leía una variable sin especificar el alcance, la primera coincidencia gana.Con CF8, podría haber más ámbitos en esa lista, no lo he comprobado.Cuando hace esto, corre el riesgo de obtener un valor de un ámbito cuando lo espera de otro;lo cual es una pesadilla para depurar...Te lo aseguro.;)

En resumen: Insinuando el alcance de una variable (en el conjunto) no es una idea terrible (aunque normalmente lo especifico de todos modos);pero infiriendo El alcance de la variable (en lectura) está generando problemas.

No hacer un alcance explícito en el alcance de las variables puede funcionar, pero no es una buena idea y, sinceramente, es la única razón no En mi opinión, es por pereza.Si abarca todo explícitamente 1) evita problemas potenciales y 2) hace que el código sea más fácil de leer porque no hay duda de en qué alcance se encuentran 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 la confusión y evita efectos secundarios extraños que pueden surgir si no se aplica explícitamente el alcance.

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

Sin embargo, creo que las mejores prácticas sugerirían que, de hecho, utilice el identificador de variables al acceder a esas variables.En mi opinión, cualquiera que encuentre su código en el futuro y esté buscando en 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 más de detalle a mis UDF de CFC creando una estructura local:

<cfset var local = structNew() />

Luego pongo todas mis variables locales en esa estructura y hago referencia a ellas de esa manera para que mi código se vea así:

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

Después de leer sus respuestas, esto 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 que ya es detallado.

Por supuesto, hay una pequeña excepción, ya que Soldarnal señalado, donde se requiere calificar una variable con alcance variable.Eso es si tiene una función variable local con el mismo nombre.(Pero probablemente no deberías hacer eso de todos modos).

Dejando a un lado las mejores prácticas, creo que también podría depender de cómo accederá a sus cfc. No he tenido ningún problema en omitirlos al crear objetos y acceder a ellos desde coldfusion.Sin embargo, creo que podría ser necesario al acceder y/o mapearlos de forma remota a través de ActionScript en Flex/Flash.

Aquí hay una muy buena Referencia del alcance de CFC de Raymond Camden.Personalmente, prefiero hacer un hash 'propio' para evitar toda confusión (tenga en cuenta que no uso el alcance de las '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>

  ...
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top