As everybody knows you should var scope ALL local function variables inside ColdFusion components, and these variables must be declared at the top of your function before any other code. If you place other code above a “var” scoped variable in your method signature an exception will be thrown.
Depending on how you define you methods this will probably be fine, but I got to thinking recently on how this works with exception handling within your function, specifically for try/catch blocks.
As you can’t add code above your var scoped variables there is no way to wrap your var scope block in a try/catch block. With this being the case you *may* have problems if an exception is thrown when you var scope a local variable.
An example of what I’m talking about:
In the fictional example shown above we have a method which returns a users work schedule, the first thing done is retrieving an instance of User from the UserService. As this has been set at the same time we var scope our variable (oUser), what happens if the call to getUserService().getUser() throws an exception? The exception would bubble up to the calling template (the template that called getWorkSchedule()) which might be fine but might also be unexpected.
This is just food for thought, it may be that instead you want to define your method like:
Here we take the approach of always declaring our local variables as empty strings or integers etc (simple values) before setting explicit values into them. This means all your variables are cleanly defined and you can catch any possible exceptions if you need to inside the try/catch.
The only is that is feels like a bit of double handling because I need to <cfset> my variables twice…
How do other people handle this? Lend me your thoughts

19 Comments
Yeah, it’s kind of annoying, but I’ve done that a lot. Same story with cflock for race conditions. Or for that matter cfquery although because of DataFaucet I rarely write them (minus the occasional query-of-query). But I’ve seen a lot of places where guys neglect to var scope a query because it doesn’t occur to them that the name attribute of their cfquery tag is setting a variable just the same way cfset does. And cfdirectory or cffile although those are less common.
A technique i picked up, i think, from Ben Nadel’s blog: declare one local structure and create all other variables as this structure’s keys.
then any vars you create in the function are created as local.varname:
,
,
etc, etc, etc
very simple and extremely useful.
@Azadi - I don’t do that for functions, seems a waste to me. Definitely for class variables where I typically use something like variables.instance which has lots of benefits
But for functions I think it’s overkill. Everything is “local” otherwise it’s referenced by a getter or variables.instance.xxx
Having them as a struct in a function can be helpful sometimes when you’re debugging the function because you can just dump the struct. Most of the time my functions don’t have enough local variables for that to be a big deal though. But if you had a function where you were doing stuff in a try-catch or a cflock like is mentioned in the blog entry, it would also eliminate the extra lines of cfset to “dummy vars” at the top.
@Ike
>Most of the time my functions don’t have enough local variables for that to be a big deal though.
Agreed.
>it would also eliminate the extra lines of cfset to “dummy vars” at the top
Good point but you lose out on introspection/documentation whether automated or for developers reviewing the method
> Good point but you lose out on introspection/documentation whether automated or for developers reviewing the method
I interpret that as a preference thing… Although there are occasional exceptions, most of my functions aren’t long enough or complex enough for me to get lost on using a struct to hold the temp vars. But then that could also just be me and the way my brain works.
I can see what you’re saying, I guess it depends on the developer and their environment. If I was working on a multi-developer project I’d like to ensure consistency, also there’s no gurantee that I (or other developers) might end up writing a method which is substantially longer than others. I’m thinking a composed method which is acting somewhat as a “controller” method etc.
Striking a balance between consistency and readability is the key.
Michael,
I usually have a Local scope defined as the first line for most of my functions.
#
#
# …
#
#
#
> Striking a balance between consistency and readability is the key.
Yep, that’s the ongoing challenge.
@Hem - Sorry about that, I must have a look into allowing special characters. I’m considering a port to mangoblog soon, will probably look at it then.
I like local scope because I only have to do it once. One issue is if for some reason you have a query of queries. I haven’t chased this one down yet but if I have a query named local.beerQuery and then try to later do a q-o-q and have something like select * from local.beerQuery, ColdFusion doesn’t seem to recognize local.beerQueer. Like I said, I haven’t chased this one down but it’s the one time I’ll do some extra var’s at the top.
@Allen - Yep, that won’t work with QoQ because from Ben Nadel’s blog:
“LOCAL is a reserved word in SQL and ColdFusion Query of Query SQL. The solution: use the [ ] notation”
FWIW I generally do the same, declaring empty local variables immediately after the arguments declarations, then explicitly populating them later. That’s one thing that the New Atlanta people got right with Blue Dragon. You can var scope a variable anywhere within the function block.
I’ve run into the same issue with name conflicts in the word “local”. Instead of using “local” as the structure name for your local variables, you can use “private” (that’s what we do at my company) or another non reserved word. A personal issue I have with that is that adding “private” or “local” before every single variable quickly makes code unreadable. If it’s a personal project where I’m not following our usual coding standard, I prefer shorter names like “loc” or “pvt” - less typing, less in between my variable names.
I used to just declare all the local variables up front in every method and not put them in a structure (even thought I was aware of this workaround), but after running that code through varScoper, I realized it was making me miss way too many variables so I stopped!
The whole issue is silly, I sure hope that Centaur removes the “top of the function block” restriction on var scoping.
@Rachel
>The whole issue is silly, I sure hope that Centaur removes the “top of the function block” restriction on var scoping.
Agreed! Maybe you have the inside scoop as to whether this really will be resolved
>but after running that code through varScoper, I realized it was making me miss way too many variables so I stopped!
I know what you mean, I typically run everything through varScoper every few days just to be safe. But also generally speaking I try to keep my methods small and compact so hopefully much like comments…there isn’t a need to use a specific struct for this.
>The whole issue is silly, I sure hope that Centaur removes the “top of the function block” restriction on var scoping.
Just thought I’d add another +1 for this because it really is ridiculous.
Yeah, I’ve thought the top-of-function restriction was silly ever since CF5 personally.
Let’s not forget the bigger picture. The real problem isn’t were we use the var keyword but that we have to use it at all. Variables in methods should have been private unless otherwise specified from the start. By again going against the grain, ColdFusion created a bunch of busy work for ColdFusion developers for what now? The last 5 years? 7?
@Allen - agreed +5 hehe. It is certainly crazy, I think I even heard along the grapevine that this will be resolved in Centaur. Let’s hope so.
I don’t think I would describe it as “against the grain”… This is the way JavaScript works with the exception that JavaScript allows you to declare new local variables with var anywhere in the function. And my understanding is that JS is far from the only language in which that’s true. Personally I comparatively consider the fact that “this” means “public” instead of “private” or the fact that output=”true” is the *default* for new functions are much more “against the grain” than the use of var.
But Adobe will also have to add new language constructs to support a change to the use of var, which I believe will be in the form of another attribute in the function or in the CFC to turn on or off the current default behavior that tells it to create variables in the private variables scope when the scope isn’t explicitly declared. Which means you’ll still have to remember to apply it (just like you do with JavaScript) — although hopefully it will be a bit easier especially since I believe you’ll be able to declare it at the cfcomponent tag. Even at the cffunction tag it should be much more manageable.