0

ColdFusion 8 Gotcha

ColdFusion

Well, sort of a gotcha.  It is actually a new feature that can cause you some grief depending on how you have done things in the past.

The application I am working on was started in CFMX7, but since 8 shipped before we went live I was able to talk my boss into upgrading.  Probably 80% of the code was complete before we upgraded so we were not able to take full advantage of CF8, but of course like any good developer I have been refactoring to CF8 as time permits depending on where I am working in the system.

This is a fully OO system so we are using a lot of different design patterns, one of them being the facade pattern, which is implemented over the session among other places.  Our session facade is pretty simple and handles all reads and writes to and from the session.   For example, if you wanted to put and get some variable called foo:

 

The way our sessionFacade works is that you can do a put(key, value), get(key), or delete(key).  At that point it acts pretty much how you would expect.  In order to keep you from accidentally borking a copy of what is in the session, the sessionFacade attempts to return by value.  

Pre-CF8, you could do a duplicate on anything that wasn't some kind of object.  Structs, arrays, and simple values are easy to duplicate, objects, not so much.  It would have been possible to write some kind of custom object duplicator but that was more effort than I wanted to go through, so the sessionFacade just did a test to see if anything being returned was an object (or contained an object), and if so, returned by reference instead of by value.  This was no big deal as long as you knew enough about the sessionFacade to be careful how you treat those references ..

Well, as it turns out, the miracle of encapsulation failed in this case and some enterprising developer realized that since objects were being returned by reference instead of by value, some interesting things were possible.  This enterprising developer just used the reference returned by the get function instead of making a local reference to the object.

No big deal right?  Except that once I realized it (I was working on something that used sessionFacade for some other purpose), I went ahead and "fixed" sessionFacade to return everything by value, as CF8 allows duplicate() to be called on objects, too.  Should have worked fine as long as nobody was treating the reference passed by the get() method as a reference .. whoops.

Ultimately this led to a number of difficult-to-figure out bugs; every time the get() method was called and the resulting reference used to set some property, a different copy of the object was being set (since a new copy was created via duplicate() every time).

The moral of the story:  CF8's improved duplicate() function is great but if you are working with facades or factories be careful that you are treating the returned reference by value if you choose to alter the implementation of the interface. 

tags:
ColdFusion

Search