2009-02-19 22 views
13

Estoy creando una API, y dentro de cada método hago una llamada a un método de registro para la auditoría y solución de problemas. Algo como:¿Puede un método ColdFusion cfc determinar su propio nombre?

<cffunction name="isUsernameAvailable"> 
    <cfset logAccess(request.userid,"isUsernameAvailable")> 
    ...... 
</cffunction> 

Me gustaría evitar repetir manualmente el nombre del método. ¿Hay alguna manera de determinarlo programáticamente?

He visto GetMetaData() pero solo devuelve información sobre el componente (incluidos todos los métodos) pero no se menciona el método que se está utilizando.

Respuesta

1

Bien puede probar esto:

<cffunction name="getFunctionName" returntype="any"> 
     <cfset meta =getMetaData(this)> 
     <cfreturn meta.functions[numberOfFunction].name> 
    </cffunction> 

He intentado varias cosas, y esto no es precisos como las funciones parecen ser añadido a la gama de funciones en orden alfabético inverso. Esto parece limitar (y no resolver el problema). Me imagino que se podría invocar un código nativo de Java, pero voy a tener que investigarlo.

This y This parecen interesantes las funciones internas relacionadas.

Re: La otra respuesta en coldspring. Encontré this in depth article en los metadatos de función con coldspring.

pregunta relacionada: How to get the name of the component that’s extending mine in ColdFusion?

11

por lo que ahora 3 maneras.

Si está utilizando ColdFusion 9.0 o superior, ahora hay una función llamada GetFunctionCalledName(). Devolverá lo que estás buscando. http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WS7cc222be8a31a47d-6e8b7083122cebfc8f2-8000.html

O

Uso ColdSpring y programación orientada a aspectos (http://www.coldspringframework.org/coldspring/examples/quickstart/index.cfm?page=aop) para manejar esto para usted.

O

Use un cfthrow para generar un seguimiento de pila que tiene la información para usted:

<cffunction name="determineFunction" output="FALSE" access="public" returntype="string" hint="" > 
<cfset var functionName ="" /> 
<cfset var i = 0 /> 
<cfset var stackTraceArray = "" /> 
<cftry> 
<cfthrow /> 
<cfcatch type="any"> 
    <cfset stacktraceArray = ListToArray(Replace(cfcatch.stacktrace, "at ", " | ", "All"), "|") /> 

    <!---Rip the right rows out of the stacktrace ---> 
    <cfloop index ="i" to="1" from="#ArrayLen(stackTraceArray)#" step="-1"> 
     <cfif not findNoCase("runFunction", stackTraceArray[i]) or FindNoCase("determineFunction", stackTraceArray[i])> 
      <cfset arrayDeleteAt(stackTraceArray, i) /> 
     </cfif> 
    </cfloop> 

    <!---Whittle down the string to the func name ---> 
    <cfset functionName =GetToken(stacktraceArray[1], 1, ".") /> 
    <cfset functionName =GetToken(functionName, 2, "$")/> 
    <cfset functionName =ReplaceNoCase(functionName, "func", "", "once")/> 

    <cfreturn functionName /> 
</cfcatch> 
</cftry></cffunction> 

Mi recomendación es usar getFunctionCalledName, o si no en CF 9 Coldspring, ya que probablemente comprarte otras cosas

+0

buena llamada en el coldspring, pero se podría pensar que no sería tan complicado. – ethyreal

4

Estoy de acuerdo con tpryan. ColdSpring hace esto muy fácil. Sin embargo, aquí hay otra alternativa. En lugar de analizar el seguimiento de la pila, puede analizar el archivo CFC.

<cffunction name="foo" displayname="foo" hint="this is just a test function" access="public" returntype="string"> 
    <cfset var test = getFunctionName(getMetaData().path, getPageContext().getCurrentLineNo()) /> 
    <cfreturn test /> 
</cffunction> 

<cffunction name="getFunctionName" hint="returns the function name based on the line number" access="public" returntype="string"> 
    <cfargument name="filepath" type="string" required="true" /> 
    <cfargument name="linenum" type="any" required="true" /> 
    <cfset var line = "" /> 
    <cfset var functionName = "" /> 
    <cfset var i = 1 /> 
    <!---- loop over CFC by line ----> 
    <cfloop file="#ARGUMENTS.filepath#" index="line"> 
     <cfif findNoCase('cffunction', line, 1)> 
      <cfset functionName = line /> 
     </cfif> 
     <cfif i EQ ARGUMENTS.linenum><cfbreak /></cfif> 
     <cfset i++ /> 
    </cfloop> 
    <!---- parse function name ----> 
    <cfset functionName = REMatchNoCase("(\bname=[""|'])+[a-z]*[""|']", functionName) /> 
    <cfset functionName = REMatchNoCase("[""']+[a-z]*[""']", functionName[1]) /> 
    <cfset functionName = ReReplaceNoCase(functionName[1], "[""']", "", "all") /> 
    <!---- return success ----> 
    <cfreturn functionName /> 
</cffunction> 

Lo anterior se escribe para ColdFusion 8. cfloop añadido soporte para recorrer al borde archivos por línea (y no lee el archivo en la memoria). Hice algunas pruebas comparando el método de rastreo de pila con el análisis de archivos. Ambos funcionaron igual de bien en un CFC pequeño que se llama directamente desde una única plantilla de CFM. Obviamente, si tiene CFC muy grandes, el método de análisis podría ser un poco más lento. Por otro lado, si tiene un rastro de pila grande (como si está utilizando cualquiera de los marcos populares) entonces el análisis de archivos puede ser más rápido.

- = = Viva ColdFusion -

1

pensé en otra forma que podría funcionar.

instalación de un OnMissingMethod algo como esto:

<cffunction name="onMissingMethod"> 
    <cfargument name="missingMethodName" type="string"> 
    <cfargument name="missingMethodNameArguments" type="struct"> 

    <cfset var tmpReturn = ""> 
    <cfset var functionToCallName = "Hidden" & Arguments.missingMethodName> 
    <cfset arguments.missingMethodArguments.calledMethodName = Arguments.missingMethodName> 
    <cfinvoke method="#functionToCallName#" argumentcollection="#Arguments.missingMethodArguments#" returnvariable="tmpReturn" /> 
    <cfreturn tmpReturn> 
</cffunction> 

entonces el nombre de cada uno de los métodos regulares con un prefijo ("Oculto" en este ejemplo), y marcarlos como privado. Así que mi ejemplo inicial se convertiría en:

<cffunction name="HiddenisUsernameAvailable" access="private"> 
    <cfset logAccess(request.userid,Arguments.calledMethodName)> 
    ...... 
</cffunction> 

Ahora todas las llamadas serán interceptados por onMissingMethod, que agregará el nombre del método a los argumentos que van pasando al método real.

Las desventajas que veo al respecto son que la introspección ya no funciona correctamente, y debe usar argumentos con nombre para llamar a todas sus funciones. Si no utiliza argumentos con nombre, los argumentos cambiarán aleatoriamente el orden en la estructura missingMethodNameArguments.

+0

¡eso es creativo! Nunca pensé en un contenedor de funciones. – ethyreal

Cuestiones relacionadas