I have programmed ColdFusion for over 15 years, but never came across this. Here's a code to replicate the behaviour:
<cfset _run()>
<cffunction name="_run">
<cfset variables.dataArray=ArrayNew(1)>
<cfset local.data={
area="profile"
}>
<cfset _append(data=local.data,field="name")>
<cfset _append(data=local.data,field="phone")>
<cfdump var="#variables.dataArray#" label="dataArray">
</cffunction>
<cffunction name="_append">
<cfargument name="data" type="struct" required="yes">
<cfargument name="field" type="string" required="yes">
<cfdump var="#arguments#" label="arguments">
<cfset arguments.data.field=arguments.field>
<cfset ArrayAppend(variables.dataArray,arguments.data)>
</cffunction>
As you can see this is what I do:
- Initing an array in the variables scope to make it globally accessable
- Initing a struct (local.data) in the local scope
- Appending first field item (name) by invoking the data to the _append function
- Appending second field item (phone) in the same manner
This code will result in the following output:
As you can see, the code results in an array with duplicate entries, when you might expected that the first index should have field="name". As you also can see, the value of data that is invoked to _append the second time, contains the property "field" with the value "name". It seems to linger in the arguments scope from the first time we called the function? How is this possible. I thought the arguments scope was isolated to inside the cffunction tag?
But if I replace the _append function with this:
<cffunction name="_append">
<cfargument name="data" type="struct" required="yes">
<cfargument name="field" type="string" required="yes">
<cfdump var="#arguments#" label="arguments">
<cfset local.data=Duplicate(arguments.data)>
<cfset local.data.field=arguments.field>
<cfset ArrayAppend(variables.dataArray,local.data)>
</cffunction>
it will give the following output:
As you can see, making a duplicate of the arguments.data before appending "field" to it, solves the problem. Note that just doing:
<cfset local.data=arguments.data>
was not enough.
Can someone explain this behaviour of the arguments scope?
So after some research, I found this on Adobe Coldfusion Documentation Page (Bolding of text done by me):
This was an eye opener for me, and it will keep me out of trouble in the future :)