Be Careful With the ‘local’ Scope When Migrating from CF8 to CF9

One of the really nice “fixes” included in ColdFusion 9 from a developer’s perspective is the inclusion of an implicit “local” variable scope into which variables created within the body of a <cffunction> tag are placed by default. Previously, developers had to manually add a “var” keyword to variables that should only exist within the confines of the function.

One of the ways of simplifying this that gained some traction among various developers prior to the release of ColdFusion 9 was to “var” a single variable at the top of the function as an empty structure then store any additional variables needed in the function inside it. Many folks, myself included, named this structure “local” so that it would be readily apparent that the values inside were local to that function. This approach worked fine and dandy on ColdFusion 8 and below.

I recently migrated one of my clients to ColdFusion 9 and not long after the client started getting isolated reports from his people having javascript errors in a data management application that uses AJAX-driven forms talking to CFCs.  At first these were very isolated and we weren’t able to reproduce the error, but, as time went on, the reports became more widespread. As I was troubleshooting this over the weekend, I discovered that we were getting javascript errors when trying to interact with this RemoteFacade CFC about 40% of the time.

Using Firebug, I was able to watch the results come back from ColdFusion and noticed a very odd trend. Approximately 60% of the time, the JSON returned from the remote CFC call was as expected. In the other 40%, one of the main data structure names was an arbitrary, machine-generated name instead of the name we had specified in the code.

Here is an example of what we were expecting in the JSON returned from the RemoteFacade.cfc method:

{"DATA":{"CANEDIT":true,"RECORDDATA":{"Field1":"value1"} } }

This is an example of what we would get back from the same request when we would see the javascript errors

{"___IMPLICITARRYSTRUCTVAR5":{"CANEDIT":true,"RECORDDATA":{"Field1":"value1"} } }

See the difference?  Our “DATA” key was named completely differently which caused javascript to throw some error saying that variableName.DATA did not exist.

After looking over the ColdFusion code for quite a while and doing some step debugging with FusionDebug I had an idea.  I changed all the function-specific structures I had been using from:

<cfset var local = structNew() />   ....<cfreturn local />

to:

<cfset var ret = structNew() />   ....<cfreturn ret />

Once I changed those throughout the code base and reinitialized my application, all the javascript errors that we’d been experiencing across multiple request types went completely away.

I have an unconfirmed theory that in using the name “local” for my structure, ColdFusion was sometimes getting “confused” on what to return–ColdFusion’s built-in local scope or the method-specific variable I had named local. I don’t really have any way to prove that beyond a shadow of a doubt, but when I made the change, all my errors went away, so I decided chalk it up as a lesson learned for future development and move on to the next problem.  Needless to say the client was happy that the issue was fixed and I can say I learned something that day.

Leave a Comment