When to Use the Variables scope.

While formatting code for the upcoming Fusion Authority Quarterly Update, I had to actually write down all the rules I personally use for code formatting. Some of them are common sense, some seem kind of strange until you think of them, and some go against the current 'best practices'.

Let's start off with the use of the Variables scope. By default, any standard variable set in ColdFusion is set to the Variables scope. This means that other than a single exception, there is never a reason to declare the Variables scope when setting a variable

<CFSET Variables.Name="michael">

All this does is make your code longer. No speed increase, no performance boost and almost no value in documentation.

The only exception I make to this rule is when setting 'Global' CFC variables.
Normally, any variable set within a CFC is set to the 'global' Variables scope (the Variables scope for the entire CFC). If the variable name has been VAR-ed in a function, then it's set to the local Variables scope of that function and disappears when the function is finished running. You MUST ALWAYS VAR local variables. Must, must, must. (If you do not then you get into issues of writing inadvertant global variables and possibly making your CFC use lots of extra memory.)
If the variable being set has not been VAR-ed, then it is set to the 'global' Variables scope of the CFC itself. This means it exists as long as the CFC does. When I'm setting a variable to the global Variables scope, I always prefix it with "Variables." to make it clear that it's global within the CFC and not local to the function.
The only effect this has is to give a visual cue in your code to tell you where the data is being set. This use of the Variables prefix for documentation is different than the use of it outside a CFC. In a normal template, there is only a single Variables scope. Inside a CFC, there are two so making a differentiation is important.

There are two reasons to use the Variables prefix when outputting data. The first is when you're in a CFOUTPUT or CFLOOP dealing with a query, and the query has a variable of the same name as one in the Variables scope. In such a case, the query variable has precedence and you need to use the Variables prefix to gain access to the other one. The second reason to use the Variables prefix is when you want to check if a variable exists in the Variables scope only. In such a case, you want to be specific to prevent ColdFusion from looking in a half dozen other scopes before saying that the variable does not exist (a waste of processing).

So the bottom line is: Use Variables.Variablename:

  • when setting a global variable within a CFC
  • within a query loop where a Query scope variable has the same name as a Variables scope variable.
  • when doing any sort of validation where you want to be specific about what variable you're validating

Anything else is just longer code.

Related Blog Entries

Comments
charlie griefer's Gravatar back in the "old days", I never scoped my local variables. I used to actually laugh when I'd come across code that did have them explicitly scoped, since it wasn't "necessary".

but somewhere between then and now, I got into the habit of explicitly scoping all variables (inclucing local). is it longer code? sure. marginally. but I think the benefits outweigh the small amounts of extra typing.

you mention that there is "almost no value in documentation". true...but subjective. for me to explicitly see my scopes makes it easier to read my code. i know i didn't indavertently forget to scope a variable (i'm old..my mind is feeble...it happens). people working in my code after me don't have to guess whether or not i meant to place the variable in the local variables scope or if i just got careless and didn't scope. if the need arises, i can do a ctrl-F in my IDE of choice to find my local vars easier. and finally...if i'm correct in my beliefs regarding "scope hunting"...ColdFusion will search the query scope and the arguments scope before it searches the local (variables) scope. that's certainly not going to make for a noticable difference in page execution...but it's still less efficient than telling CF to go directly to the variables scope.

For those reasons (and i'll admit also due to the simple fact that old habits die hard)...I'm more than willing to continue typing in "variables." i can type it quickly enough, and my code is that much more explicit (which to me means better documented and easier to maintain).

i'm pretty sure the world will go on either way...i just wanted to present another perspective on the subject :)

charlie
# Posted By charlie griefer | 6/6/06 7:44 PM
Ryan Guill's Gravatar I disagree personally. I write variables. everwhere needed. The only way it would work not to write it for the variales scope is if you scoped absolutely every other variable in any other scope. And then, when you use a variable without a scope, you have to wonder if the author just 'forgot' to scope the variable or really meant it to be in the url or form scope, etc. In my opinion, any and every variable should be scoped, the only exception being VAR scoped variables.
# Posted By Ryan Guill | 6/6/06 8:01 PM
Michael Dinowitz's Gravatar What if you have a variable that may come in as a form or as an url variable. What prefix do you use? :)

When I see my code, if I don't see a prefix then it can only be one of three things. A variable scope variable(most common), a query variable (when inside a query based CFOUTPUT or CFLOOP), or a variable that can either be coming from a form or an url. I REALLY try to avoid that last case and put in comments when I can't avoid it.

The main issue I see when using the variable prefix all of the time is when setting variables inside a CFC. How do you keep track of what variables are being set to the local function vs. what's being set to the global? What happens if you miss VAR-ing a variable? What if you have a long function and have to keep going to the top of it to see if the variable is VAR-ed and local.

One solution is to use the This scope to hold global info but a LOT of people are against that. If Adobe added the ability to control access to the This scope on a per CFC level then it would be more 'palatable' to some.
# Posted By Michael Dinowitz | 6/6/06 8:33 PM
Ben Nadel's Gravatar I am not sure if this is or ever was an issue, but I remember reading somewhere that if you do NOT scope your variables into the Variables scope, then you could refer to them using the Variables scope or not. However, if you explicitly scope a variable (ex. VARIABLES.Foo) then you can no longer refer to it without the Varbiables scoping. I am not saying you would ever want to switch like that, but that's just something I remember.

Personally, I am a big fan of scoping. It makes things easier to read (in my head, but then again, things need to be properly indented, and without word-wrap on for me to make heads or tails of anything). I however prefer the REQUEST scope and I use an ATTRIBUTES scope which is a combo URL/FORM union.
# Posted By Ben Nadel | 6/6/06 9:13 PM
Ryan Guill's Gravatar If I have a url or form variable then it is scoped of course! You can post a form to a page with url variables, and so there is absolutely no reason not to scope them as well. Query variables too! Especially importaint when you may be looping over a parent query and a sub query inside of it. Or if you have query columns that may share the same or even similar variables as exists in your local variable scope.

Inside of a cfc, all variables that are global to the cfc are explicitly stated with the variables scope. Anything local doesnt have a scope, but thats only because there is not one. If adobe created a scope for those to exist such as local I would use it. In fact, I have heard of some developers that will create one structure locally at the top of a function call, called local, and all local variables they use go inside of that. The usually have other reasons as well, but it makes for certain that you know where a variable comes from and what its life expectancy is.

The This scope, while similar to the variables scope inside of a cfc, allows the variables that exist inside of it to be accessed through the object itself directly. You generally do not want to expose those variables outside of the object. If you want a protected This scope, you want to use the variables scope inside of the component/object. Also, many developers use a special key in the variables scope in an object so that you realize that it is specific to that instance of the object, such as variables.properties or variables.instance. All of my global object variables, those being used throughout the object in various functions exist in a variables.instance structure.

The main thing im getting at is I always consider it best practice to be as explicit as possible. It makes debugging easier, maintainence easier, and to me just makes the code easier to read and reduces the need for some comments.

Also Ben, I dont think thats true, at least not in cf7. Always scope your variables and you never have to wonder.
# Posted By Ryan Guill | 6/6/06 10:09 PM
John Elkins's Gravatar I have to agree with most of the comments here. Scope all your variables. It makes everything easier. The added value may not be tangible from a performance perspective, but from a code maintenance level it's invaluable.
# Posted By John Elkins | 6/7/06 4:24 PM
Tariq Ahmed's Gravatar My humble 2 cents...

An effective standard or process is one that is simple, and therefore not conditional. "don't scope except when..." and "always scope except for..." requires people to have to know your rules.

Scoping is good, so scope always and remove the guesswork. At a new job I'm at I've taken over a huge legacy app and it is a pain in the a** to work with. And a big reason for that is it's hard to tell where things are getting set and where they're coming from. Sure, without them being scoped you can access and manipulate them no problem - but if they were fully scoped you eliminate where they come from initially.

So if you say, scope everything but the Variables scope... and you come across "<cfif x eq "y">... Ok, is this guy following the rules, and therefore its implicitly a Variables variable, or is it a URL variable and he forgot to scope it.

Keep processes/procedures/rules simple by minimizing subjective decision points (do I scope in this xyz situation?). E.g "where you want to be specific about.." <-- Not good, this is your personal determination as to when to be specific.

Keep it simple. Scope always.
# Posted By Tariq Ahmed | 6/14/06 2:45 PM
Michael Dinowitz's Gravatar I think people are reading a little too much into what I posted. I didn't say never scope, I just said that when using a very specific scope, the rules I use are to limit its use. When using other variables it is of utmost importance to scope them as they are 'lower' down on the food chain from the Variables scope and if your not specific it can lead to a waste of processor power as the CF server looks through a half dozen scopes to find what may or may not exist.

That's why I said that one of my exceptions to scoping with the variables scope is when doing validation. It limits the range of the validation to a specific scope.

I'm going to have to post a follow up on the other variable scopes ASAP. I've been kind of tied up printing a ColdFusion Technical Journal to post more. :)

(My next post will garner a LOT more controversy as it shows how breaking a few 'best practices' can lead to a very nice performance increase, but that's later)
# Posted By Michael Dinowitz | 6/14/06 5:06 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.9. Contact Blog Owner
House of Fusion | ColdFusion Jobs @ House of Fusion | Fusion Authority