Sorry to yell (well, we don't have to assume all exclamation marks are equivalent to yelling) but this email came in to me this morning and it is very troubling for me:
I have a question for you about varScoper and CF9. As I understand it, in CF9 all unscoped variables in a function are placed into a protected local scope, thereby killing the need to use the var x = "" line to scope them.If that understanding is correct, does this make varScoper obsolete in CF9? Our team in upgrading to CF9 in the near future, and trying to identify if running code through varScoper needs to continue to be a part of our code review processes or not.
The answer is an unequivocal no. You must still continue to var scope your variables in UDFs and CFC methods. There is no change in this respect. ColdFusion 9 only makes two related changes:
- The var scope previous was an "unnamed" scope. ColdFusion 9 fixes this by creating a scope called local. Like other ColdFusion scopes you can treat this as a structure.
- Because there is an implicit local scope, you can now skip the var keyword and use "local." instead. So given the line used in the quote above, you could var scope X by rewriting it as local.x="". To me, this is still "var scoping", it just gets there via a different path.
So long story short - yes - you still need to var scope in CF9. The varScoper tool is still an important and necessary part of your testing/deployment strategy.
Archived Comments
I am glad I havnt stopped "VARing". Sometimes yelling helps! ;)
One more related change, the var declaration no longer needs to be grouped at the top of the CFC. For example, if you need to var a loop control variable in the middle of your CFC you can now do that without throwing an exception.
Good point Seth. I freaking love that change - especially for loop iterators. Also note you can _repeat_ var statements. So you can do var i=1 more than once. Pointless - but it means you can be extra careful.
For my CF8 apps I got into the habit of just doing this with my CFC methods
cfset var local = {};
and then appending to the struct from there. I realize this is nothing earth shattering as people were doing it years before I even figured it out. What killed me was when I did this by accident in several places
cfset local = {};
That's when I started pulling my hairs out, in pure denial that I did anything wrong. Ugh.
I haven't yet focused on learning new features in CF9 -- first time I have done that since I started in CF back in 4.5 (honestly I'm a bit tired of CF). With that said I did follow a bunch of discussion leading up to its release and recall something about an option in the CFC to make unscoped variables in CFC functions local by default. Am I imagining this or was this discussed/previewed but not in the final build?
I don't remember that - then again - my memory is the suck lately.
In CF9 as long as one uses the local scope within a method, there is no need for the var keyword to make it private?
Correct.
local.x = 1
is the same as
var x = 1
One big gotcha in CF8 that I have not yet tested in CF9 is that implicitly created variables are not var scoped.
For instance if I do:
<cfhttp url="http://foo.com">
and reference #cfhttp.filecontent#
That is not threadsafe!
Totally bit me in the ass on a production application.
Instead you need to do:
<cfset var httpresult = '' />
<cfhttp url="http://foo.com" result="httpresult">
and then reference #httpresult.filecontent#
I had var scoped every variable in my app...except for the one I didn't create myself and let CF create for me.
Yep, result= was added to tags that drop stuff in the variables scope like that. I believe _all_ of them (cfhttp, cfquery come to mind) have this feature.
If we are using SweetTweets.cfc, are we going to have a problem, with respect to the local keyword being used, when we upgrade to CF9? Do we need to upgrade this? Thanks for your help.
I'm using SweetTweets on this blog, which is running CF9. No problems with it.
Ray,
As of CF9, are you now writing your components entirely in CFScript, or are you mixing CFML and CFScript?
If you are using CFScript entirely, what are you using for VarScoping? Mike's varscoper does not work in cfScript based on components.
dave
I'm trying to do all my CFCs in script, and for var scoping, I'm just trying my best to be careful.
Ray,
Someone posted a decent antlr grammer of CFML/cfscript on github(https://github.com/denuno/c....
I built a var scope checker on top of it. (along with a few only checks). It consumes (most) CFML and CFScript successfully.
https://github.com/ryaneber...
Feed back welcome.
- Ryan.
That's pretty cool. Only thing that bothers me is the name - cfbugs. Sounds like a bug tracker. ;)
Hmm. Good point. It started as a reference to FindBugs - the Java code
analysis tool we've been using for a couple years.
It's all about 'finding' bugs, not 'reporting' them.
The term 'Lint' seems to be popping up a lot lately. JSLint, CSSLint,
etc. Maybe CF-Lint would be more appropriate. Though 'lint' didn't mean
anything to me up until a couple months ago. you?
I'm all about the lints. I'd go for CFLint (no dash).
I guess so. You just blogged about it a couple days back. :-) I'm happy with your name suggestion - I'll hit that tonight.