• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Disable cffunction accepting undeclared arguments?

New Here ,
Jul 17, 2014 Jul 17, 2014

Copy link to clipboard

Copied

I have a lot of function calls with long lists of arguments and sometimes they can get mismatched (invoke with invokeargument status, function argument status_code). Coldfusion allows this to happen and makes the undeclared argument available in the arguments scope. Is there any way to disable this behavior so it only allows declared arguments and throws and error when it gets passed an argument that it doesn't expect?

TOPICS
Advanced techniques

Views

420

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 19, 2014 Jul 19, 2014

Copy link to clipboard

Copied

First of all, if a function has a long list of arguments, say, more than 5 or 6 arguments, then it is complex. It is likely to be doing too many things. As a rule, a function should have just one responsibility. You should split such complex functions up into 2 or more separate functions.

To avoid ambiguity, use the name of the arguments when you call the function. For example, suppose that myFunc has arguments arg1, arg2,..., arg6, all of which are optional. Then you could call it as follows: myFunc(arg3="Journal",arg5="2014").

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 21, 2014 Jul 21, 2014

Copy link to clipboard

Copied

The nature of this project requires the long lists of arguments, and I do use names with optional arguments. The issue I'm having is when I invoke a function expecting "status_code" as an argument with an argument of "status" instead. The function executes with status_code at its default value and status just sitting in the arguments scope unused. This is never intentional, but happens on occasion. I would like coldfusion to throw an error any time there is something in the arguments scope that is not an expected argument.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 21, 2014 Jul 21, 2014

Copy link to clipboard

Copied

Please bear with me: I still don't get it. What do you mean by, "when I invoke a function expecting "status_code" as an argument with an argument of "status" instead. The function executes with status_code at its default value and status just sitting in the arguments scope unused" ?

Could you just paste a little code here to illustrate? Thanks.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 21, 2014 Jul 21, 2014

Copy link to clipboard

Copied

I think I get it now. The argument name is status_code, but what gets into the function is arguments.status instead of arguments.status_code. Right?

If so, you should check where the function is called with the argument status_code. There might be a space between status and _code. In any case, at the point where the function is called, retype the name status_code, just to be sure.

Bradleythall wrote:

I would like coldfusion to throw an error any time there is something in the arguments scope that is not an expected argument.

Use code similar to that in bold.

<cffunction name="testFunc">

<cfargument name="arg">

<cfargument name="myArg">

<cfargument name="myOtherArg">

<!--- List arguments in alphabetical order to enable comparison --->

<cfif listSort(StructKeyList(arguments),"textnocase","asc") is not "arg,myArg,myOtherArg">

    <cfthrow message="An unexpected argument was passed to the function">

</cfif>

<cfreturn "Success!">

</cffunction>

<cfoutput>#testFunc(someOtherArg=1)#</cfoutput>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 21, 2014 Jul 21, 2014

Copy link to clipboard

Copied

Your understanding was correct. I was hoping to find a coldfusion setting to enable some sort of "strict mode" on function calls, but using this code did the job and only required a paste into each function. Note: works only on CF 9+

<!--- Include this invoke in any function to check the arguments --->

<cfinvoke component="validation" method="verify_arguments">

<cfinvokeargument name="accepted_arguments" value="#ARGUMENTS#">

<cfinvokeargument name="declared_arguments" value="#GetMetaData(Evaluate(GetFunctionCalledName())).parameters#">

</cfinvoke>

<!--- Function it calls for reference --->

<cffunction name="verify_arguments" access="public" output="yes">

<cfargument name="accepted_arguments" required="yes">

<cfargument name="declared_arguments" required="yes">

<cfif ArrayLen(declared_arguments) IS NOT ArrayLen(accepted_arguments)>

<h2 class="warning">Function has accepted more arguments than were declared.</h2>

<h3>Declared Arguments</h3>

<cfdump var="#declared_arguments#">

<h3>Accepted Arguments</h3>

<cfdump var="#accepted_arguments#">

</cfif>

</cffunction>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 26, 2014 Jul 26, 2014

Copy link to clipboard

Copied

LATEST

The issue arises because Coldfusion is weakly typed. As such, it cannot support method overloading. So I understand what you are aiming at. You could nevertheless improve the design.

At the moment, you give responsibility for checking the arguments to the function itself. That design reduces cohesion. Ideally functions should be defined such as to perform one service. Making them to validate arguments, on top of the task they each have to perform, introduces unnecessary complexity, hence reduced cohesion.

The 'Design By Contract' (DbC) paradigm suggests a solution. The validation of arguments - as you have done - is an example of a precondition in DbC. A precondition is carried out as follows:

1)  by the caller of a function;

2)  before the function runs.

Delegating the task to the caller is inevitable. In software design, you delegate tasks and responsibilities ideally to the party that has the most information necessary to perform them. (This is sometimes called the G.R.A.S.P. pattern). In this case, that party is the caller of each function. For the caller is the specialist who, better than anyone else, is aware of the parameters that are used to call a function.

This improved design leaves your above validation code basically unchanged. Above all, it has the tremendous advantage of leaving your functions intact. Imagine how much refactoring, debugging and hair-tearing this would save you if you had, say, 2000 functions.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation