Calendar
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
Recent Entries No recent entries.
Recent Comments
Flex: Making Scrollbars Follow Focus
Daryl Banttari said: Still works fine for me. As I tab from field to field, the scrollbar adjusts to ensure the field wi...
[more]
Flex: Making Scrollbars Follow Focus
newchild said: your autoscroll class doesent scroll automaticly, even in your example. So what exactly is that for?...
[more]
Reviving the Lost Craft of Writing Specification Documents
Tanya said: Thank you:)
[more]
ColdFusion SQL Injection
Sam Singer said: Will this run on os x?
[more]
Reviving the Lost Craft of Writing Specification Documents
Nat Papovich said: Hi Greg, yes that was intentional. It's just an example, after all :)
Tanya, take a look at the Pow...
[more]
Archives By Subject
Business of Software (5) [RSS]
ColdFusion (321) [RSS]
Conferences (7) [RSS]
Databases (88) [RSS]
Flex & Flash (109) [RSS]
Fusebox (87) [RSS]
General Development (33) [RSS]
Google (9) [RSS]
Hardware (5) [RSS]
JVM & Java (132) [RSS]
Linux (20) [RSS]
Macintosh (1) [RSS]
Miscellaneous (254) [RSS]
Performance (8) [RSS]
SeeFusion (36) [RSS]
Shan's Simple Examples (7) [RSS]
User Interface (3) [RSS]
Windows (5) [RSS]
Archives By Poster
Daryl Banttari (11)
Nat Papovich (33)
Patrick Quinn (36)
Shannon Hicks (22)
Steve Nelson (22)
Tyson Vanek (3)
The VAR keyword is idiotic
Macromedia (Not Adobe, I assume) screwed up with this one.
The var keyword needs to go away.
Think about this for a minute. When was the last time you wanted to NOT use the VAR keyword in a CFC? Reread that sentence. I'm not suggesting we want to not var our variables. I'm suggesting we ALWAYS want to var our variables. I'm suggesting we NEVER-NOT want to var our keywords (double-negative).
Sorry about that rant. In other words, I'm suggesting that setting variables inside of a cffunction should automatically be local variables, even if you do not use the var keyword. Right now they are automatically global variables. We already have a global scope, the request scope. We don't need another one.
CFFUNCTION should treat unscoped variables as local variables. I.e. that variable ONLY exists inside the cffunction that created it. Similar to how variables are local in a cfmodule.
This is good syntax:
<cfset myvariable="hello world">
</cffunction>
This is bad syntax
<cffunction name="myfunction">
<cfset var myvariable="hello world">
</cffunction>
IMO these two bits of code should do EXACTLY the same thing. Please Adobe, deprecate the var keyword, it is idiotic.


Second, just to clarify, non-var scoped variables go into the variables scope of the containing CFC (they become instance data). So this is quite different than a "global" variable like the request scope. The two serve very different purposes. Just wanted to make sure other readers understand that!
Yes it would break existing code if someone is making use of turning it off (not using it). That's why I ask the question "do you ever want to NOT use it?"
I'm not convinced anyone is NOT using it... on purpose. Plenty of people are not using it by accident. Like me. Whoops, I just found another one.
Steve, easy on the double negatives. It's confusing ;)
Don't stop ever not never not be not such a sissy-wussy-pants. If you can.
My biggest problem is that the var keyword is inconsistent with the rest of the CF Language. There is nothing else like it in the language.
I'm sure the CF team is cautious about making changes that affect how things work, though. I do not expect the var keyword to go away.
My one addition to your request is that the "un-named function local" scope be given a name, perhaps "local".
So this:
<cffunction name="myfunction">
<cfset local.myvariable="hello world">
</cffunction>
is the same as this:
<cffunction name="myfunction">
<cfset var myvariable="hello world">
</cffunction>
Then we 'experienced developers' could go back to blaming all the var scoping problems on people who do not properly scope their variables.
Plus... the "this" scope with all it's flaws AND the "request" scope do everything that an "un-var'd" variable does. So there are basically 3 solutions (well sort of) to the same problem. An unscoped variable should be local to that function. A "this" scope variable should be global to the CFC itself, like it already is. A "request" scope variable should be global to then entire request.
Steve, this seems to miss one of the most crucial scopes: the variables scope of the CFC. This is private instance data and is critical to doing OO programming with CFCs. The THIS scope is public which nukes any chance of encapsulating the internal state of the CFC.
In a .cfm file, foo = 42; is identical to variables.foo = 42; and thereafter references to foo are identical to variables.foo. And variables is the page scope.
Since that's so common to CFers, the thinking was that CFCs should work the same way. variables is the "page" scope - shared between functions in the CFC - and unqualified references use the variables scope.
In particular, in CFMX 6.0, that was your *only* choice.
In CFMX 6.1, a new function-local scope was introduced and, to preserve backward compatibility and the core axiom of foo == variables.foo above, a new declaration syntax was introduced, var.
There's a lot of code out there that does *not* use variables. as a qualifier for variables-scope names in CFCs and that code would break if you changed the lookup rule.
Having said that, I agree that inside CFCs, we more usually want new variables to appear in function-local scope instead of variables-page scope and it would be nice to have an option somehow to change that default behavior. Either through a server setting (in CF Admin) or cfprocessingdirective or maybe as an attribute on cfcomponent and/or cffunction. The latter has the advantage of granularity so you could migrate code function-by-function to the new style although, technically, the cfprocessingdirective would be the "right" approach since this is a compile-time behavior change (and still allow you to change the behavior on a per-file basis to maintain compatibility with third-party CFC code).
BTW, I was goofing around with some code. I only see two situations where un-var'd variables really cause a problem.
1) in an "init" method (well, any method that cfreturns "this")
2) in a method that calls another method from the same CFC
Those are the only two situations that I've come up with that var'ing seems to make any bit of difference. But Nat says he has some big horror story about un-var'd variables. I'm begging him to blog about it. Maybe we all say PLEASE.
The THIS scope is public, which means any external code can call <cfset myCFC.someThisScopeVar = "" /> and modify the internal state of the component directly, without going through a method. The entire point of encapsulating the internal state of a CFC is to hide the internal implementation of the CFC and force all client code (anything that uses the CFC) to go through a method call to have the CFC do anything. That includes modifying private variables.
The whole reason no one uses the THIS scope is because it is public and lets any client code modify the CFC's internal state directly. This blows away the whole point of making internal object data private and forcing client code to use the object's API (its public methods). Make sense?
Although that isn't my reason for not using the THIS scope. I just haven't come across why the THIS scope would make my code easier to read/understand. That's my biggest concern.
God knows why one would want to have a function touch a "variables" variable. But it is possible. So with this in mind I do not think "VAR" will be taken away.
Brian, nice explanation about "this".
Standard concept: most languages provide getter/setter functions on objects. Can you tell me how to set a "read only" value for the "This" scope? No, of course not. You can in PHP, ASP, even in Flex! Yet, there are technical difficulties that prevent it in CF. In fact it would be great if when we set a value it called the setter automatically... WITHOUT calling a method when the "standard" for UML is setting or getting a value with the "attribute". (How are we supposed to use common UML tools to design CF objects when our public variables lack common read/read-only type functions?) ... and I do like how PHP and Flex let you set a function to automatically handle the set function of a class attribute set.
If you want a read-only value for a CFC instance variable, you make the setter private and the getter public. This is not complicated. You can't make a variable private in the THIS scope because the THIS scope is public, just as it is in JavaScript. Still not understanding what the confusion is here.
<cfset var local = structNew() />
<cfset local.anotherVariable = 'hello' />
<cfset local.anotherStuct = structNew() />
etc, once you have the initial var, all local. vars are local.
I also like to scope everything. That way, I can tell the difference between LOCAL scoped variables and ARGUMENTS scope variables that might have naming conflicts.
To be honest, I think the best possible solution would be to make LOCAL a build in scope for all CFFunction scopes. Basically, build in the var LOCAL = StructNew() line of code. That way, you can still explicitly set something as being local, but no need to set up the scope.
Not only does this save you a step, it make your code more understandable as it self-documents the availability of a variable.
If we got rid of the VAR keyword, I suspect that it would be harder to tell where keywords were supposed to be available. Although I guess if you force the scoping of non-local variable, that would also help.
Very true, and I have done that a bunch. The only time I can ever see that being a problem is when my arguments variable A and my local variable A have different meanings (in which case the two different scopes is needed). But again, that is a special case.
When I do use the ARGUMENTS scope as a local scope, I tend to feel bad, like I am cheating, or misusing it... but I get over that and realize that ARGUMENTS is neither living nor does it have feelings :)
There also may be an issue with this during recursion. Specifically when overwriting an arguments scoped variable. Although I'm not 100% sure about this.