ColdFusion array is one unique data structure in ColdFusion. Unique in the sense that this is the only data structure that is passed by value and not by reference. I do feel it is a limitation sometimes but thats legacy and can not be changed. (You would not want us to break your code. Would you? ;) )
There does exist one hack if you absolutely need to pass the array by reference. Here is a code snippet that uses pass by reference.
<cfset x = ArrayNew(1)>
<cfloop from=1 to=5 index=i>
<cfset Arrayappend(x,"something")>
</cfloop>
<cfset x = CreateObject("java", "java.util.ArrayList").init(x)>
<cfset foo(x)>
<cfset foo(x)>
<cfset x[8] = "after the method call">
<cfset x[9] = "end of method call">
<cfset foo(x)>
<cfdump var="#x#">
<cffunction name="foo">
<cfargument name="arr">
<cfset ArrayAppend(arr, "from function")>
</cffunction>
So what did we do here? We created an ArrayList from the ColdFusion array. Since ColdFusion Array is an implementation of java.util.List, almost all Array functions work on all implementations of java.util.List. And this list implementation will not be passed by value but will be passed by reference. Thats the power of using java in ColdFusion !
7 comments:
Rupesh, I agree. Passing the array by value does seem like a limitation. I like the stuff you have above... but be careful, if memory serves, this works on 99% of things, but bombs for ArrayResize(). But other than that, this is good solution.
That is why I said **almost** all and not ALL.
Most of the time, you would call resize pretty much soon after creating the array when you know that your array is going to store this many element. You can do the same thing for the ArrayList that you created.
So you can use
<cfset myarr = CreateObject("java", "java.util.ArrayList").init(1000)>
<cfset myarr.addAll(x)>
<cfset x = myarr>
Word up, I didn't mean to come off sounding attacking. I was just clarifying that the *almost* I think only is ArrayResize(). I think the initialization technique you just commented on is a great idea. I didn't realize that you could init with a size. Thanks for the hot tip!
Hey Ben.. you didn't. I am sorry if I sounded that way :)
Hope to see a CALLBY argument in the next CF version:
<CFARGUMENT CALLBY="value|reference|default" ...>
;-)
thanks for posting this. i just stumbled over this "feature" and was about ready to throw my laptop out the window... ;)
Post a Comment