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
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


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
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.
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.
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.
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.
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)