Follow up to flaw using local variable in ColdFusion 9

It seems that a minority of people do not seem to understand the actual problem in my previous post, so I thought I would make a few changes to give a better description of the problem.

But first lets look at ColdFusion 8 for a moment.

ColdFusion prior to ColdFusion 9, had no concept of private variables in functions and this was a major issue, when it came to thread safe components and methods.

ColdFusion introduced the var keyword to help, but this was a real after thought and was full of problems right from the beginning but it was the best we had at the time.

So in a method in a component it is very legal to write code like this.

<cfset var local = getProperties() />

Now lets get this straight, I am not one to use it this way. However I can see benefits to doing this and I'll describe that in a minute. In ColdFusion 8 this will return a struct and define it to the variable scope local, in ColdFusion 9 the function call is totally ignored.

So even though this line of code is exactly the same as doing this.

<cfset var local = {username='andrews', password = 'password'} />

Which both ColdFusion 8 and ColdFusion 9 will happily run.

The major problem now is trying to follow DRY (Don't repeat yourself) pattern, so if you find yourself defining a structure in the same manner it makes extreme sense to refactor your code to call a method to return the structure. Which is how this problem has risen.

So for some reason even though ColdFusion will except an explicit struct definition, it will not accept a function returning any structure, it will just not run that function.

So lets look at the next problem this creates, and that would be to refactor the code to look something like this.

<cfset var local = {} />
<cfset local = getProperties() />

And why is this a problem, well it is a problem because it now does a very weird thing in ColdFusion 9, which doesn't happen in ColdFusion 8.

That is that the first line sets up a local structure, but the second one defines the local back into a variables scope. This can be seen in the line debugger as such or you can do this to test it for yourself.

<cfset var local = {} />
<cfset local = getProperties() />
<cfdump var="#local#" />
<cfdump var="#variables#" />

And to make it even worse for ColdFusion 9. If I then create some code to do this.

<cfset local.strVersion = SERVER.ColdFusion.ProductVersion />
<cfset local.strLevel = SERVER.ColdFusion.ProductLevel />

These are stored in the first local definition, so we ColdFusion has now ended up with 2 local variables, one the local scope the second as a struct in the variables scope.

I hope this clears it up some more, this will break existing ColdFusion 8 applications and Adobe has tried to be backward compatible, but anyone who uses this method is going to have to refactor their code.



  • Aidan Kane's Gravatar eek. that's a problem. I'd wondered what the impact of adding a scope called local was going to be. unfortunately in all of our code we do exactly what you're doing here. all of our functions begin with: <cfset var local = {} />

    i've not installed cf9 yet but I have a fear that this is not going to be good news for our existing codebase!
    # Posted By Aidan Kane | 10/30/09 9:54 PM
  • Andrew Scott's Gravatar If you use it like

    <cfset var local = {} />

    You will be fine, if you try to pre populate in the example above then you will be in trouble.
    # Posted By Andrew Scott | 10/30/09 10:13 PM