Arguments exist even if not declared (bug?)

0 views
Skip to first unread message

Matt Williams

unread,
Oct 22, 2007, 3:21:30 PM10/22/07
to cfc...@googlegroups.com
Maybe it is known or expected, but I was surprised it works. If you
pass arguments to a function, but don't declare them via the
cfargument tag, it exists anyway. You lose the name of the argument,
but can still access it via the arguments struct.

*************The CFC:

<cfcomponent output="false">

<cffunction name="functionOne">
<cfdump var="#arguments#" label="functionOne dump">
<cfset functionTwo(argumentCollection=arguments) />
</cffunction>


<cffunction name="functionTwo">
<cfdump var="#arguments#" label="functionTwo dump">
</cffunction>

</cfcomponent>


**********The CFM
<cfset myTest =
createObject('component','testArgCollection').functionOne('something','or
another','hello world')/>

**********
The dump shows the 3 values passed into functionOne. Because I blindly
pass all arguments via argumentCollection, both dumps have all
parameters.

Again, maybe this is expected, but I think it is something to watch
out for in case you're passing more than you think (or want).

--
Matt Williams
"It's the question that drives us."

Larry C. Lyons

unread,
Oct 22, 2007, 4:20:16 PM10/22/07
to cfc...@googlegroups.com
Its been like that since the intro of UDF's in CF5. You can also
access them via an array as well. If you go through some of the code
from CFLib.org, you'll see a fair number of UDF with this sort of
syntax:

function formToHidden(){
//a variable for iterating
var key = "";
//should we exlude any? by default, no
var excludeList = "FIELDNAMES";
//a variable to return stuff
var outVar = "";
//if there is an argument, it is a list to exclude
if(arrayLen(arguments))
excludeList = excludeList & "," & arguments[1];
//now loop through the form scope and make hidden fields
for(key in form){
if(NOT listFindNoCase(excludeList,key))
outVar = outVar & "<input type=""hidden"" name=""" & key & """
value=""" & htmlEditFormat(form[key]) & """>";
}
return outVar;
}

In this case you can pass in an optional argument using the cfscript structure.

regards,
larry

On 10/22/07, Matt Williams <mgw...@gmail.com> wrote:
>
> Maybe it is known or expected, but I was surprised it works. If you
> pass arguments to a function, but don't declare them via the
> cfargument tag, it exists anyway. You lose the name of the argument,
> but can still access it via the arguments struct.

--
The real problem is not whether machines think but whether men do. -
B. F. Skinner -

Sean Corfield

unread,
Oct 22, 2007, 5:06:16 PM10/22/07
to cfc...@googlegroups.com
On 10/22/07, Matt Williams <mgw...@gmail.com> wrote:
> Maybe it is known or expected, but I was surprised it works. If you
> pass arguments to a function, but don't declare them via the
> cfargument tag, it exists anyway. You lose the name of the argument,
> but can still access it via the arguments struct.

How would you reference those arguments otherwise?

Could you explain *why* you thought the arguments scope would not
exist if no arguments were passed? I'm curious as to your logic here.
You know that you can always pass more arguments to a function than
are declared (or maybe not and that's what led you to this position)?
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

Matt Williams

unread,
Oct 22, 2007, 5:34:49 PM10/22/07
to cfc...@googlegroups.com
On 10/22/07, Sean Corfield <seanco...@gmail.com> wrote:
>
> On 10/22/07, Matt Williams <mgw...@gmail.com> wrote:
> > Maybe it is known or expected, but I was surprised it works. If you
> > pass arguments to a function, but don't declare them via the
> > cfargument tag, it exists anyway. You lose the name of the argument,
> > but can still access it via the arguments struct.
>
> How would you reference those arguments otherwise?

Not that I would want to, but it could be done via arguments.1,
arguments.2, etc.

>
> Could you explain *why* you thought the arguments scope would not
> exist if no arguments were passed? I'm curious as to your logic here.
> You know that you can always pass more arguments to a function than
> are declared (or maybe not and that's what led you to this position)?

It wasn't that I didn't think the arguments scope doesn't exist if no
arguments were passed, but rather any arguments not declared weren't
available to the function.

I've always assumed (and that was my first mistake) that if the
argument wasn't declared in the function (via cfargument), then it was
somehow dropped or ignored. Yes I did know you can pass more arguments
than are declared, but again, I didn't know they were actually in the
function that was called.

I found this to be of interest because of some of my coding habits
(that probably need to be changed) where I pass the entire Mach II
event arguments to my service layer
(argumentCollection=event.getArgs()). The service layer's function
declares only the needed arguments. I then loop over those arguments
to set the values in a bean.

Until now, I didn't realize I was looping over more than just what I
declared, but anything within the struct returned by event.getArgs().
With proper naming conventions it probably would never be an issue,
but I thought it would be good to be aware of nonetheless.

Sean Corfield

unread,
Oct 22, 2007, 6:22:08 PM10/22/07
to cfc...@googlegroups.com
On 10/22/07, Matt Williams <mgw...@gmail.com> wrote:
> Not that I would want to, but it could be done via arguments.1,
> arguments.2, etc.

Not legal variable names! Has to be arguments[1], arguments[2].

> I've always assumed (and that was my first mistake) that if the
> argument wasn't declared in the function (via cfargument), then it was
> somehow dropped or ignored. Yes I did know you can pass more arguments
> than are declared, but again, I didn't know they were actually in the
> function that was called.

Ah, OK. Yes, if you declare, say, two arguments a and b and then pass
three arguments, you'll have arguments["a"], arguments["b"] and
arguments[3] - and you can reference the first two as arguments.a and
arguments.b as well.

> Until now, I didn't realize I was looping over more than just what I
> declared, but anything within the struct returned by event.getArgs().

OK, I see where you're coming from. Yes, if you loop over the
arguments array / struct (it's both) then you will see every argument
passed, regardless of what is declared.

Brian Kotek

unread,
Oct 22, 2007, 8:32:18 PM10/22/07
to cfc...@googlegroups.com
This is part of the reason why I created my FormUtility CFC (http://formutils.riaforge.org/index.cfm). You can name form elements like "user.firstName", " user.lastName", etc. The CFC will convert this into a struct called "user" with keys "firstName" and "lastName", etc. This makes it much easier to pass just want you want into the service layer from the controller. It does arbitrarily nested structs, arrays, arrays of structs, etc., based on the form field names.
Reply all
Reply to author
Forward
0 new messages