2009-02-19 8 views
13

私はAPIを作成しています。各メソッド内で、監査とトラブルシューティングのためのロギングメソッドを呼び出します。次のようなものがあります。ColdFusion cfcメソッドが独自の名前を判別できますか?

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

手動でメソッド名を繰り返すことは避けてください。プログラム的に決定する方法はありますか?

私はGetMetaData()を見ましたが、のコンポーネント(すべてのメソッドを含む)についての情報を返しますが、現在どのメソッドが呼び出されているかについては何も返しません。

答えて

1

さてあなたはこれを試してみてください:

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

私はいろいろなことを試してみた、との機能が逆のアルファベット順に関数の配列に追加しているように見えるとして、これは正確ではありません。これは制限されているようだ(問題を解決していない)。私は、いくつかのネイティブjavaコードが呼び出される可能性があると思いますが、それを調べる必要があります。

ThisおよびThisは、関連する内部機能の面白い読書のようです。

Re:コールドスプリングのもう一つの答え。私はcoldspringの関数メタデータでthis in depth articleが見つかりました。

関連質問:How to get the name of the component that’s extending mine in ColdFusion?

11

だから今、3つの方法。

ColdFusion 9.0以降を使用している場合、GetFunctionCalledName()という名前の関数が追加されました。それはあなたが探しているものを返します。 http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WS7cc222be8a31a47d-6e8b7083122cebfc8f2-8000.html

OR

使用ColdSpringとあなたのためにこれを処理するために、アスペクト指向プログラミング(http://www.coldspringframework.org/coldspring/examples/quickstart/index.cfm?page=aop)。

OR

あなたのための情報を持っているスタックトレースを生成するのcfthrowを使用します。

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

それはおそらくれるように私の推薦は、CF 9 ColdSpringにgetFunctionCalledNameを使用するか、そうでない場合はされるだろうあなたに他のものを買う。

+0

coldspringでの通話はいいですが、これは複雑ではないと思います。 – ethyreal

4

私はt/tpryanに同意します。 ColdSpringはこれを非常に簡単にします。ただし、別の方法があります。スタックトレースを解析する代わりに、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> 

上記のColdFusion 8 CFLOOPために書かれているが(と、メモリにファイル全体を読み取らない)行ごとにファイルを上ループのサポートを追加しました。私は、スタックトレースメソッドとファイル解析を比較して、いくつかのテストを行いました。両方とも、単一のCFMテンプレートから直接呼び出される小さなCFCで同等に機能します。明らかに、非常に大きなCFCを使用している場合は、解析方法が少し遅くなる可能性があります。一方、大きなスタックトレースがある場合(人気のあるフレームワークを使用している場合など)、ファイルの解析が高速になる場合があります。

- =ビバのColdFusion = -

1

私は仕事ができる別の方法を考えました。

セットアップこのようなOnMissingMethod何か:

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

は、その後の接頭辞(この例では「隠し」)との定期的なメソッドのそれぞれに名前を付け、プライベートとしてマーク。だから私の最初の例はなる:

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

今、すべてのコールは、実際のメソッドに渡される引数にメソッド名を追加しますonMissingMethod、によってインターセプトされます。

私が見ている欠点は、イントロスペクションが正しく機能しなくなり、名前付き引数を使用してすべての関数を呼び出す必要があることです。名前付き引数を使用しない場合、argsはmissingMethodNameArguments構造体の順序をランダムに変更します。

+0

thats creative!私は関数ラッパーについて考えたことはありません。 – ethyreal

関連する問題