Coldfusion variable scopes in CFCs

While fixing my cfTrigger framework recently, I realized that I have messed up the scopes of variables inside cfcs seriously! I omitted the var keyword for local variables and used This keyword where it should have been Variables. So before continuing to fix it, I decided to take a step back and learn again in a more proper way what variable scopes are available in Coldfusion cfcs and how to use them correctly.

There are many scopes for variables in Coldfusion such as Application, session, form, url, public, private, etc. but in this article I am only interested in the scopes related to cfcs. These include the This scope variables, Variables scope variables, variables defined with the var keyword and those defined without any keyword or scope. Keep in mind that these are considered inside a cfc context.

Findings Summary

Below is the summary of Coldfusion variable scopes related to cfcs:

Declare with Example Scope Notes
This <cfset This.name = "khoa"> Public Available throughout the entire cfc and also to the caller
Variables <cfset Variables.name = "khoa"> Private to the cfc Available throughout the entire cfc but not to the caller
Var <cfset var name = "khoa"> Private to the function Available to the function where the declaration appears, not available to any other functions inside the cfc or the caller
[NOTHING] <cfset name = "khoa"> Same as Variables This is essentially the same as using the Variables scope. So it's better to explicitly write the Variables scope to avoid confusion

Example

Due to the example file being a little bit long, I won't post it here. But please download them at the end of this article to test them out yourself. In the example, I have a Person class (person.cfc) that has a number of local variables, VARIABLES (cfc) variables, THIS variables and some declared without any scope or keyword. I then use a cfm file to display them to show you which ones are available at which scopes. Download and open the files and read on to see my explanation of the example.

What I did in the example:

  1. Call a function to display the Variables scope variables from inside the object. This returns:

    • Variables that are defined with the explicit Variables scope, and
    • Variables that are defined without using any scope

    This happens regardless of where the variables are defined: in the same function, in another function or at the top of the cfc outside all functions.

    Private variables, retrieved from internally
  2. Call a function to display the This scope variables from inside the object. This returns:

    • Variables that are defined with the explicit This scope

    Again, this happens regardless of where the variables are defined.

    Public variables, retrieved from internally
  3. Display the list of variables available to the caller from outside the object. This returns:

    • Variables that are defined with the explicit This scope

    This is the same list of variables as in the second call above.

    Public variables, retrieved directly from the caller

Notes: I only display the simple values in this example. If you dump the Variables or This scope, you will have much more such as other variable types and function definitions.

Takeaways

  • Always declare local variables with the var keyword, or you will (very likely) receive unexpected results
  • Use VARIABLES scope to store variables that you want to be shared, available, across the entire cfc. This is especially useful in the init method, where you initialize the object and would like to store some object properties for later use.
  • Use scope (or the var keyword) when declaring variables inside cfc to keep them organized and avoid variables appearing where you don't expect them. Without a scope, it will default to the VARIABLES scope. So it's always good to explicitly give it a scope.
  • In Coldfusion, This is public while it is generally private in most other languages. And as in any other languages, try to limit the number of public variables. Only expose as much as you need to. That means limit the use of This.

Download example

5 Comments

  • Stephen Moretti
    15 Sep 2010, 4:17 AM

    Just for clarification; What version of ColdFusion Server did you test against?

  • John Barnes
    15 Sep 2010, 5:08 AM

    You could also mention the explicit local scope in CF9. So you can now do

    <cfset local.name = 'johnny' />

    Which is private to the function, I find it cleaner and more logical than using the var scope.

  • Vinh Khoa Nguyen
    15 Sep 2010, 6:23 AM

    @Stephen, I tested this against CF8 and Railo 3.1

    @Johnny, that is great news! I haven't tried out CF9 yet so I'm not aware of that scope. When using CF8, I always wish there is such a scope for local variables so that I could cfdump and see all the local variables at once. Thanks for letting me know :-) It is definitely cleaner, can't wait for it to come to Railo.

  • Unibands
    11 May 2011, 12:03 PM

    @Vinh Khoa Nguyen

    If you want to recreate this type of behaviour in earlier versions, here's a workaround:

    At the top of the cffunction create ONE var variable called 'local' that creates a structure.

    <cfset var local = {} />

    Now you can create variables on the fly which are simply stored in this structure like:

    <cfquery name="local.myQuery">
    ...
    </cfquery>

    The beauty of this, is that if you ever upgrade to CF9+ then you can just remove the first line that declares your structure and everything will still work the same.

    Mikey.

  • Vinh Khoa Nguyen
    11 May 2011, 8:48 PM in reply to Unibands

    Interesting enough, this is exactly what I have been doing lately! The only downside is more typing as we have to keep typing local.a, local.b, etc.

Leave comment

Hi, please enter your real name and email address. The email won't be published. Comments are moderated and will appear after checked for spams.

Reply to :