views:

579

answers:

3

I have a ColdFusion function "foo" which takes three args, and the second two are optional:

<cffunction name="foo" access="public" returntype="any">
    <cfargument name="arg1" type="any" required="true" />
    <cfargument name="arg2" type="any" required="false" default="arg2" />
    <cfargument name="arg3" type="any" required="false" default="arg3" />

    ...

    <cfreturn whatever />
</cffunction>

I want to call foo, passing in arg1 and arg3, but leaving out arg2. I know that this is possible if I call the function using cfinvoke, but that syntax is really verbose and complicated. I have tried these two approaches, neither works:

<cfset somevar=foo(1, arg3=3) /> <!--- gives syntax error --->
<cfset somevar=foo(1, arg3:3) /> <!--- gives syntax error --->
+12  A: 

You have to use named arguments throughout. You can't mix named and positional arguments as you can in some other languages.

<cfset somevar = foo(arg1=1, arg3=3) />
Patrick McElhaney
+2  A: 

if you use named args you have to name the first too

<cffunction name="foo" access="public" returntype="any">
    <cfargument name="arg1" type="any" required="true" />
    <cfargument name="arg2" type="any" required="false" default="arg2" />
    <cfargument name="arg3" type="any" required="false" default="arg3" />

    <cfreturn arg2 & " " & arg3>
</cffunction>


<cfset b = foo(arg1:1,arg3:2)>
<cfoutput>#b#</cfoutput>
Nick
+11  A: 

Or.. you can use ArgumentCollection

In CF9 or above...

<cfset somevar = foo({arg1=1, arg3=3})>

In CF8 or above...

<cfset args = {arg1=1, arg3=3}>
<cfset somevar = foo(argumentCollection=args)>

If CF7 or below...

<cfset args = structNew()>
<cfset args.arg1 = 1>
<cfset args.arg3 = 3>
<cfset somevar = foo(argumentCollection=args)>
Henry
This is how I generally prefer to do it. I'm more than likely determining which arguments to include at runtime. It's nice and easy to wrap <cfset args.foo=bar> inside a <cfif> block.
Al Everett
As Al implies, you should update your examples to show that a major benefit of ArgumentCollection is that it allows you to build/manipulate the structs in a flexible fashion, before sending it to the function - your current examples are just a long-winded way of using all named arguments. :)
Peter Boughton
Also worth noting is that you can mix-and-match named arguments and ArgumentCollection in a single function call.
Peter Boughton