Esta es una reimpresión de blog post I did anterior al 13 de junio de 2007. ¡He estado utilizando este método durante bastante tiempo y funciona de maravilla! YMMV.
¿A quién no le gustan las funciones definidas por el usuario (UDF)? Si ha realizado alguna programación, es probable que la haya utilizado extensamente. El mayor problema que las personas tienen con ellos es cómo incluirlos y organizarlos en su aplicación.
Lo que he encontrado que la mayoría de la gente hace es crear un Utils.cfc o UDFs.cfc y cortar y pegar sus UDF que quieren utilizar en el componente como se demuestra a continuación:
<!--- UDFs.cfc --->
<cfcomponent output="false">
<cffunction name="init" access="public” returntype="Any" output="false">
<cfreturn this>
</cffunction>
<cffunction name="myUDF1" access="public" returntype="Any" output="false">
</cffunction>
<cffunction name="myUDF2" access="public" returntype="Any" output="false">
</cffunction>
</cfcomponent>
Una vez que tener todas las UDF que su aplicación usará pegadas en su componente, deberá hacer que las UDF estén disponibles para su aplicación. Casi todos los que he visto lo cargan por el componente en el alcance de la aplicación. La siguiente línea se coloca en el onApplicationStart()
si está usando Application.cfc o con sólo añadir que en el Application.cfm si se está utilizando lo siguiente:
<cfset application.functions = CreateObject("component", "udfs").init()>
Cualquiera que usted está usando, Application.cfc o Application.cfm, los resultados son los mismos; todas sus UDF están disponibles para su aplicación y puede usarlas libremente en todas partes. La única diferencia es qué nombre de variable usa. Uso las funciones de aplicación, algunas usan application.utils o application.udfs; no importa, una vez más, los resultados son los mismos.
Hay un problema que tengo con este enfoque, sin embargo, es engorroso y el componente UDFs se volverá enorme. El problema de tener un archivo de componentes tan grande es la edición, se convierte en una pesadilla ya que desplazarse por miles de líneas de código no es muy divertido y también me he dado cuenta de que CFEclipse se atasca en archivos de gran tamaño. El colapso del código seguro proporciona cierto alivio, pero tiene que haber una mejor manera.
Lo que quería era tener solo un archivo para cada UDF que estaba usando y una forma de que mi aplicación los cargara automáticamente. La razón detrás de esto era que si necesitaba editar myUDF1
, podía simplemente abrir el archivo myUDF1.cfm
y editar lo que necesitaba. También quería poder tomar UDF del CFLib.org y simplemente colocarlas en mi aplicación sin tener que editar nada. Si alguna vez necesitaba eliminar una UDF de mi aplicación, sería tan fácil como borrar el archivo UDF y reiniciar mi aplicación.
para lograr lo que quería, he modificado mi UDFs.cfc a 11 líneas de código:
<!--- UDFs.cfc --->
<cfcomponent output="false">
<cfset variables.udfdir = GetDirectoryFromPath(GetCurrentTemplatePath()) & "udfs">
<cfset variables.q = "">
<cffunction name="init" access="public" returntype="Any" output="false">
<cfreturn this>
</cffunction>
<cfdirectory action="list" directory="#variables.udfdir#" filter="*.cfm" name="variables.q">
<cfoutput query="variables.q">
<cfinclude template="udfs\#name#">
</cfoutput>
</cfcomponent>
Entonces, ¿qué está pasando exactamente?
En pocas palabras, esto es lo que está sucediendo: Tengo un directorio llamado udfs
en el mismo directorio que tengo mi UDFs.cfc. Este es el directorio donde pongo todos mis archivos UDF CFM. Lo que UDFs.cfc hace es escanear este directorio cuando se llama y automáticamente incluye cada archivo CFM que encuentra. Por lo tanto, carga automáticamente todas las UDF en la carpeta UDFs (comúnmente llamada "mixin").
¡Así que se ha alcanzado mi objetivo! Tengo cada UDF en su propio archivo, así que no tengo que desplazarme a través de un enorme archivo de componente para encontrarla. Ahora puedo abrirlo y editarlo fácilmente. Con solo mirar el directorio, sé qué UDF está usando mi aplicación. Puedo agregar automáticamente un UDF desde CFLib.org simplemente guardando el texto del navegador en un archivo en el directorio. Además, si ya no necesito usar el UDF en mi aplicación, simplemente elimino el archivo del directorio y se elimina de mi aplicación durante el próximo reinicio. Todo esto se hace sin tener que tocar el archivo principal UDFs.cfc.
A continuación se muestra un ejemplo de cómo se ve uno de los archivos UDF CFM. El archivo se llama fullLeft.cfm
y reside en el directorio UDFs.
<!--- fullLeft --->
<cffunction name="fullLeft" access="public" displayname="fullLeft" returntype="string" output="false">
<cfargument name="str" type="string" required="true">
<cfargument name="count" type="numeric" required="true">
<cfif not refind("[[:space:]]", arguments.str) or (arguments.count gte len(arguments.str))>
<cfreturn Left(arguments.str, arguments.count)>
<cfelseif reFind("[[:space:]]",mid(arguments.str,arguments.count+1,1))>
<cfreturn left(arguments.str,arguments.count)>
<cfelse>
<cfif count-refind("[[:space:]]", reverse(mid(arguments.str,1,arguments.count)))>
<cfreturn Left(arguments.str, (arguments.count-refind("[[:space:]]", reverse(mid(str,1,arguments.count)))))>
<cfelse>
<cfreturn left(arguments.str,1)>
</cfif>
</cfif>
</cffunction>
Muy buena idea, tendré que experimentar con su enfoque. – kevink
He estado haciendo esto durante mucho tiempo con buenos resultados, también. –
Implementé esto ayer y tengo que decir que funcionó muy bien. También utilicé el enfoque para simplificar las pruebas de mi unidad recorriendo el directorio y asegurándome de que no se pueden perder funciones. Muy resbaladizo – kevink