2009-02-19 4 views
13

Tôi đang tạo một API và trong mỗi phương pháp, tôi thực hiện cuộc gọi đến phương pháp ghi nhật ký để kiểm tra và khắc phục sự cố. Một cái gì đó như:Phương pháp cff Coldfusion có thể xác định tên riêng của nó không?

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

Tôi muốn tránh lặp lại tên phương thức theo cách thủ công. Có cách nào để xác định chương trình không?

Tôi đã xem GetMetaData() nhưng nó chỉ trả về thông tin về thành phần (bao gồm tất cả các phương pháp) nhưng không có phương thức nào hiện đang được gọi.

Trả lời

1

Vâng, bạn có thể thử này:

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

Tôi đã thử những điều khác nhau, và điều này là không chính xác như các chức năng dường như được bổ sung vào mảng của các chức năng trong thứ tự chữ cái ngược lại. Điều này có vẻ hạn chế (và không giải quyết được vấn đề). Tôi sẽ tưởng tượng một số mã java gốc có thể được gọi, nhưng tôi sẽ cần phải nhìn vào đó.

ThisThis giống như đọc thú vị về các chức năng nội bộ có liên quan.

Re: Câu trả lời khác về coldspring. Tôi đã tìm thấy this in depth article về siêu dữ liệu chức năng với coldspring.

Câu hỏi liên quan: How to get the name of the component that’s extending mine in ColdFusion?

11

Vì vậy, bây giờ là 3 cách.

Nếu bạn đang sử dụng ColdFusion 9.0 trở lên, hiện tại có một hàm có tên GetFunctionCalledName(). Nó sẽ trả lại những gì bạn đang tìm kiếm. http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WS7cc222be8a31a47d-6e8b7083122cebfc8f2-8000.html

HOẶC

Sử dụng coldspring và Aspect Oriented Programming (http://www.coldspringframework.org/coldspring/examples/quickstart/index.cfm?page=aop) để xử lý việc này cho bạn.

HOẶC

Sử dụng một cfthrow để tạo ra một dấu vết ngăn xếp có thông tin cho bạn:

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

Tôi đề nghị sẽ được sử dụng getFunctionCalledName, hoặc nếu không muốn nói về CF 9 coldspring, vì nó có thể sẽ mua cho bạn một số thứ khác.

+0

cuộc gọi tốt trên coldspring, nhưng bạn sẽ nghĩ rằng nó sẽ không được phức tạp này. – ethyreal

4

Tôi đồng ý w/tpryan. ColdSpring làm cho điều này rất dễ dàng. Tuy nhiên, đây là một lựa chọn khác. Thay vì phân tích cú pháp theo dõi ngăn xếp, bạn có thể phân tích cú pháp tệp 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> 

Phần trên được viết cho ColdFusion 8. CFLOOP hỗ trợ lặp lại các tệp theo dòng (và không đọc toàn bộ tệp vào bộ nhớ). Tôi đã làm một vài bài kiểm tra so sánh phương pháp theo dõi stack so với phân tích cú pháp tệp. Cả hai hoạt động tốt như nhau trên một CFC nhỏ được gọi trực tiếp từ một mẫu CFM duy nhất. Rõ ràng nếu bạn có CFC rất lớn, phương pháp phân tích cú pháp có thể chậm hơn một chút. Mặt khác, nếu bạn có một dấu vết ngăn xếp lớn (như nếu bạn đang sử dụng bất kỳ khung công tác phổ biến nào) thì việc phân tích tệp có thể nhanh hơn.

- = Viva ColdFusion = -

1

tôi nghĩ một cách khác mà có thể làm việc.

cài đặt một cái gì đó OnMissingMethod như thế này:

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

Sau đó đặt tên mỗi người trong số các phương pháp thông thường với một tiền tố ("Hidden" trong ví dụ này), và đánh dấu chúng là tư nhân. Vì vậy, ví dụ ban đầu của tôi sẽ trở thành:

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

Bây giờ tất cả các cuộc gọi sẽ được chặn bởi onMissingMethod, mà sẽ thêm tên phương pháp để các đối số mà có được truyền cho phương thức thực sự.

Những nhược điểm mà tôi thấy là sự mâu thuẫn này không còn hoạt động đúng cách nữa và bạn phải sử dụng các đối số được đặt tên để gọi tất cả các chức năng của mình. Nếu bạn không sử dụng các đối số được đặt tên, args sẽ ngẫu nhiên thay đổi thứ tự trong cấu trúc missingMethodNameArguments.

+0

thats sáng tạo! tôi không bao giờ nghĩ về một hàm bao hàm. – ethyreal