Named Arguments In ColdFusion Depend On The Argument Collection, Not The CFArgument Tags

Posted August 11, 2010 at 9:22 AM by Ben Nadel

Tags: ColdFusion

Last night, I was laying in bed thinking about Jenna Elfman in Can't Hardly Wait (one of the best coming-of-age movies ever), when suddenly, I started thinking about named arguments in ColdFusion. I know I've probably covered this a number of times before but, I wanted to test the behavior of named arguments when no CFArgument tags were present in a function. In essence, I wanted to double-check whether named arguments required CFArgument tags; or, if the very existence of them in the ArgumentCollection was sufficient. Part of this curiosity ties into stuff Elliott Sprehn discussed at CFUNITED 2010 - but, more to come on that later.

If you look at the way ColdFusion 9's new CFScript-based tag components (ex. Query.cfc) work, it is clear that named arguments do not need to have corresponding CFArgument tags; but, since I want to build on this behavior, I wanted to run a quick test to setup a foundation for future exploration. In the following code demo, all I have is a ColdFusion user defined function that CFDump's out its arguments scope. You will notice here that the UDF does not have any predefined CFArgument tags:

  • <cffunction
  • name="doSomething"
  • access="public"
  • returntype="any"
  • output="true"
  • hint="I simply output my arguments scope to see how named arguments work without CFArgument tags.">
  •  
  • <!--- Dump out the arguments. --->
  • <cfdump
  • var="#arguments#"
  • label="Arguments Scope."
  • />
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>
  •  
  •  
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  •  
  •  
  • <!--- Create an argument collection with named arguments. --->
  • <cfset arguments = {
  • name = "Tricia",
  • hair = "Blonde",
  • isSassy = true
  • } />
  •  
  • <!---
  • Invoke our argument tester method, passing in our named
  • arguments as the argument collection.
  • --->
  • <cfset doSomething( argumentCollection = arguments ) />
  •  
  •  
  • <br />
  •  
  •  
  • <!---
  • Now, just as a test, let's try it one more time with a
  • completely different set of arguments (there's no real need
  • for this test, I just like to be thorough).
  • --->
  • <cfset arguments = {
  • name = "Deadlift",
  • weight = "315",
  • reps = "8"
  • } />
  •  
  • <!--- Test the invocation one more time. --->
  • <cfset doSomething( argumentCollection = arguments ) />

Once doSomething() - my user defined function - is defined, I create two arbitrary structs to use as my invoking argumentCollection. Calling doSomething() and passing in each struct gives me the following CFDump output:

 
 
 
 
 
 
Named Arguments In ColdFusion Depend On The ArgumentCollection Structure, Not On The CFArgument Tags. 
 
 
 

As you can see, the name-value pairs in our arbitrary argumentCollection structs are translated into the named arguments available within the CFFunction's arguments scope. While the existence of CFArgument tags can help map positional arguments to named arguments, there is nothing about named arguments that requires CFArgument tags.

This demonstration isn't ground-breaking in any way; but, as someone who is compulsive about defining CFArgument tags within my CFFunctions, I simply wanted to double-check this behavior before I moved onto some more complex concepts that leverage this functionality.




Reader Comments

Aug 11, 2010 at 9:37 AM // reply »
4 Comments

Nice reminder, I tend to forget this is possible on methods we create ourself. Will definitely try to use it more often.


Aug 11, 2010 at 9:45 AM // reply »
11,246 Comments

@Michiel,

I don't mean to imply that you *shouldn't* use CFArguments tags; they are definitely great for code readability and self-documentation. I just wanted to confirm the behavior before I started to look into something a bit more deeply.


Aug 11, 2010 at 10:07 AM // reply »
74 Comments

Jenna Elfman is one of those actresses who will make me think twice about watching a movie because I find her so annoying. However, "Can't Hardly Wait" is so good I can overlook her presence (and my friend Amber is in it, so... :)


Aug 11, 2010 at 10:18 AM // reply »
11,246 Comments

@Wendy,

Have you seen Keeping The Faith? She is excellent in that. I don't think I've seen her in much else.


Aug 11, 2010 at 10:26 AM // reply »
74 Comments

Netflixed it (at your suggestion :) and couldn't get through it because I found her so annoying. She's done a couple of tv shows, and I couldn't watch those either. She just bugs the stuffing out of me (and not just because she's a card-carrying Scientologist). Don't think I will ever get over my anti-Elfmanism.


Aug 11, 2010 at 10:28 AM // reply »
16 Comments

So what are you planning on doing? Doing some protoTypes? Method Chaining?


Aug 11, 2010 at 10:31 AM // reply »
11,246 Comments

@Wendy,

Fair enough - to each their own. I found her very much the opposite in Keeping The Faith; her character just seemed to be very endearing.

@Tim,

Elliott was doing some very interesting argument overloading trickery in his presentation. I just wanted to explore some of those concepts a bit more deeply, see what I might be able to do with them.


Aug 11, 2010 at 10:34 AM // reply »
74 Comments

Hmm... well, to be totally honest, I only watched the first scene with her in it and shut it off. Maybe I shouldn't be so narrow-minded (yes, I actually said that). I really love Edward Norton; he is such a quality actor!


Aug 11, 2010 at 11:28 AM // reply »
2 Comments

Since you're just looking to confirm the behavior, it should be noted that this is not limited to named arguments but also works for positional arguments (in CF8 anyway). I agree that this does greatly reduce code readability, but is good to know.


Aug 11, 2010 at 11:37 AM // reply »
11,246 Comments

@Jeremy,

Ah yes, good point. I think that should work pre-CF8 as well. If anyone doesn't understand what Jeremy is referring to, he means you can always reference positional arguments via the arguments scope:

arguments[ 1 ]
arguments[ 2 ]
... etc.

You can even use named-arguments to fenagel ordered arguments:

<cfinvokeargument name="1" value="foo" />
<cfinvokeargument name="2" value="bar" />

Good stuff.


Aug 11, 2010 at 11:42 AM // reply »
4 Comments

I was reading the same topic in morning...nice to see this again in evening with much better example..


Aug 11, 2010 at 12:02 PM // reply »
11,246 Comments

@Sanoop,

Awesome my man - glad to be timely on topic.


Aug 11, 2010 at 8:46 PM // reply »
19 Comments

@Ben

You couldn't pass positional arguments with argumentCollection or cfinvokeargument name="1" (etc.) before 8.0.1.

That's the reason ColdSpring and many other frameworks looked at the metadata of functions to get the argument names to use cfinvoke. The only reason not to use this feature is if you're supporting CF7.

Ideally we'll get component[method](a,b,c) syntax in CF10. Railo already supports it. We really wanted it in CF9, but they didn't get around to it.


Aug 11, 2010 at 11:00 PM // reply »
11,246 Comments

@Elliott,

Ahh, thanks for the clarification. I was not aware that that behavior was added after the CFInvokeArgument tag. As far as the component[method](), they neeeed to add that - it would make certain things so much easier.


Aug 16, 2010 at 7:29 AM // reply »
27 Comments

@Elliott,

i use:
variables.gf_stupid_cf_parser = component[method]
and then call
variables.gf_stupid_cf_parser( a,b,c )

is there a better workaround ?


Aug 16, 2010 at 9:32 PM // reply »
11,246 Comments

@Nelle,

The problem with that is that once you get the method reference out of the component, it is no longer bound to the component when it is executed. As such, once you get the reference to "gf_stupid_cf_parser ", you are executing it in the context of the variables scope and will not have access to the component's private scope.


Aug 17, 2010 at 3:35 AM // reply »
27 Comments

@Ben,

indeed, the method then has no access to the "this" scope.

for methods which need it, the approach could be modified to:
component.gf_stupid_cf_parser = component[method]
component.gf_stupid_cf_parser( a,b,c )

but the question remains, is this really the best way to do it ?


Aug 17, 2010 at 9:23 PM // reply »
11,246 Comments

@Nelle,

Ahhh, I see what you're saying; I don't think I was following you at first. That's a really interesting idea - storing the method reference *back* into the component with a known name. That's a clever idea.

I suppose, until we can do component[method](), we can still use the CFInvoke and CFInvokeArgument tags:

<cfinvoke component"#component#" method="#method#">
<cfinvokeargument name="a" value="x" />
<cfinvokeargument name="b" value="y" />
<cfinvokeargument name="c" value="z" />
</cfinvoke>

... but clearly WAY more verbose.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 25, 2013 at 10:01 PM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
@Avi, Really glad to help! @Jaredwilli, I'm finding a this image hits home with a lot of people :) Hopefully we can all work through the rough patches together! @Prateek, AngularJS has error ... read »
May 25, 2013 at 9:53 PM
Nested Views, Routing, And Deep Linking With AngularJS
@Mrsean2k, I'm glad I could help! I haven't been able to keep up with the ui-router stuff. I keep saying that I'll carve out time, but I just haven't gotten to it :( ... read »
May 25, 2013 at 9:49 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, Thanks for the book recommendations. I am looking them up right now. I can see that Object Thinking is available for the Kindle App - sweet! Also, I just recently heard Martin Fowler on the ... read »
May 25, 2013 at 9:41 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
@Chris, I'm super excited to hear that my posts are helpful. I am also loving AngularJS; but, it definitely has some caveats and some odd behaviors and some things that just don't seem to "wor ... read »
May 25, 2013 at 9:36 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Adam, @Jason, After reading these comments, I double-checked my latest implementation and I am happy to report that I am using listFirst() and listRest(). ... read »
May 25, 2013 at 9:31 PM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
@Daxesh, I am not sure I understand the question about the current node. If you already have a reference to the current node, why would you need to query for it? As for parent node, I believe that ... read »
May 25, 2013 at 10:08 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
@Ben, my question is that i want the current node with its tag and its parent node. i just want only that data. So, give me the solution for that. and remember solution is working on " xpath 1.0 ... read »
May 25, 2013 at 10:01 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
hey ben, i want get my current node tag and also want the root node tag withing. So, how can i fix it.. ! ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools