tags:

views:

809

answers:

9

In a ColdFusion Component (CFC), is it necessary to use fully qualified names for variables-scoped variables?

Am I going to get myself into trouble if I change this:

<cfcomponent>
    <cfset variables.foo = "a private instance variable">

    <cffunction name = "doSomething">
     <cfset var bar = "a function local variable">
     <cfreturn "I have #variables.foo# and #bar#.">
    </cffunction>
</cfcomponent>

to this?

<cfcomponent>
    <cfset foo = "a private instance variable">

    <cffunction name = "doSomething">
     <cfset var bar = "a function local variable">
     <cfreturn "I have #foo# and #bar#.">
    </cffunction>
</cfcomponent>
+6  A: 

It won't matter to specify "variables" when you create the variable, because foo will be placed in the variables scope by default; but it will matter when you access the variable.

<cfcomponent>
    <cfset foo = "a private instance variable">

    <cffunction name="doSomething">
     <cfargument name="foo" required="yes"/>
        <cfset var bar = "a function local variable">
        <cfreturn "I have #foo# and #bar#.">
    </cffunction>

    <cffunction name="doAnotherThing">
     <cfargument name="foo" required="yes"/>
        <cfset var bar = "a function local variable">
        <cfreturn "I have #variables.foo# and #bar#.">
    </cffunction>

</cfcomponent>

doSomething("args") returns "I have args and a function local variable"

doAnotherThing("args") returns "I have a private instance of a variable and a function local variable."

Soldarnal
Yes, the arguments takes precedence over the instance variable. I'm okay with that. It's consistent with other languages, where I would have to use this or self to reference the instance variable as opposed to the argument.
Patrick McElhaney
A: 
Adam Tuttle
Did you mean '<cfset VAR foo = "bar" />'?
Patrick McElhaney
And my example code does use the var keyword. So, um, I'm confused. :-)
Patrick McElhaney
No, I intentionally left out the "var" in that statement; it is an example of bad practice.Your example does use var, but you remove "variables." which is what I'm saying is a bad idea. See Dan Wilson's answer regarding maintainability.
Adam Tuttle
A: 

After reading your answers here's what I'm thinking:

Yes, it's safe. In general, it's not necessary or useful to explicitly specify the variables scope. It just adds clutter to an already verbose language.

Granted, there is one minor exception, as Soldarnal pointed out, where qualifying a variables-scoped variable is required. That is if you have a function local variable with the same name. (But you probably shouldn't do that anyway.)

Patrick McElhaney
+1  A: 

The simple answer to your question is: "NO, it isn't necessary"

However, I think best practices would suggest that you do, in fact, use the variables indentifier when accessing those variables. In my opinion anyone who comes upon your code in the future, and is looking in the middle of a function, will instantly know the scoping of the variable without having to scan the top of the function the local functions.

In fact, I add a little extra verbosity to my CFC UDFs by creating one local struct:

<cfset var local = structNew() />

Then I put all my local vars in that struct and reference them that way so my code will look something like this:

<cfset local.foo = variables.bar + 10 />

Bill Rawlinson
+3  A: 

Especially in CFCs, proper scoping is important. The extra 'verbosity' is worth the clarity. Having variables slip out of their indended scope will cause severe problems and very hard to diagnose.

Verbosity isn't always a bad thing. We name our functions and methods in descriptive manners like getAuthenticatedUser(), rather than gau(). Database columns and tables are best left descriptive like EmployeePayroll rather than empprl. Thus, being terse might be 'easier' when your short term memory is full of the project details, but being descriptive shows your intent and is helpful during the maintenance phase of an application, long after your short term memory has been filled with other stuff.

Dan Wilson
A: 

Best practices aside, i believe it could also depend on how your going to access your cfc's i have not had any problems leaving them out when creating objects and accessing them from coldfusion. However i think it might be needed when accessing and/or mapping them remotely via actionscript in flex/flash.

ethyreal
+1  A: 

I'll say Yes. Is it explicitly necessary? Nope. Can you get away with not doing it? Sure. Are you asking for trouble? Absolutely. If you have the following inside a cffunction:

<cfset foo = "bar" />

That will not place that variable in the function local var scope, it will place it in the CFC's global VARIABLES scope, meaning that it is available to every method of that CFC. There are times when you may want to do this, but most of the time you'd be asking for a race condition.

When any variable is being read by the server, if that variable is not explicity declared as part of a scope (REQUEST., SESSION., etc.) then ColdFusion will run ScopeCheck() to determine which scope the variable is in. Not only is this placing unnecessary overhead on your application server, it also introduces the ability for hijacking, whereby your variable is in one scope, but ScopeCheck() has found a variable of the same name higher in the precedence order.

Always, always, ALWAYS, scope all variables. No matter how trivial. Even things like query names and looping indexes. Save yourself, and those that come behind you, from the pain.

A: 

Here's a very good CFC scope reference from Raymond Camden. Personally, I prefer to make a 'self' hash to avoid all confusion (notice I don't use the 'variables' scope in the functions):

<cfcomponent>
  <cfset variables.self = structNew()>
  <cfscript>
    structInsert(variables.self, <key>, <value>);
    ...
  </cfscript>

  <cffunction name="foo">
    self.<key> = <value>
    <cfreturn self.<key> />
  </cffunction>

  ...
A: 

Not explicitly scoping in the variables scope may work, but it's not a good idea, and honestly the only reason not to is out of laziness IMO. If you explicitly scope everything 1) you avoid potential issues, and 2) it makes the code easier to read because there's no question which scope things are in.

To me it doesn't make the code more verbose (and certainly not unnecessarily verbose)--it's actually easier to read, avoids confusion, and avoids weird side effects that may crop up if you don't explicitly scope.

Matt Woodward