Object Oriented Coldfusion : 4 : The var scope

Posted on August 23, 2007

In part three of this primer, we discussed how an object’s variables scope exists only within itself and is available to any function it contains. Now we need to cover how and why to make a variable only available to a single function.

John Jacob Jingleheimer Schmidt

_His name is my name too.
Whenever my value’s changed,
You can hear the people shout,
Why isn’t this function giving me the right value?

One of the biggest problems when writing functions in objects occurs when two or more functions manipulate a variable of the same name. Since any variable that is not explicitly scoped is placed into the variables scope, not only can every function in the object read its value, every function can change its value.

Multi-threading rears its ugly head

The problem of a variable’s value being changed unexpectedly may not appear while you’re developing an application. However once your application hits production and the number of users increases, you’ll begin to see the effects of having non-var-scoped variables in your functions as reports of invalid data come pouring into the helpdesk. This is especially true for objects that are stored in the server, application or session scopes.

Let’s say you have a form.cfm that submits to form_process.cfm. While you’re developing the form, on form_process.cfm, you create an instance of FormObject.cfc to handle the data from the form.

Since you’ve created an instance of the object every time the form is submitted, then the object’s variables scope is available to the single thread that is processing the form’s submit action. If ten users submit the form, then ten threads are created, each with their own insulated instance of FormObject.cfc.

Now you decide to place FormObject.cfc into the appliction scope so you only have to create it once, instead of every time that form is submitted. At this point, when ten users submit the form, ten threads are created and they all use the same instace of FormObject.cfc.

This means that ten threads are calling functions that can alter anything in the variables scope of the object. The more threads, the more possibilites that the data inside that object is not secure.

By var scoping your function variables, you can eliminate the possibility of the object corrupting its data.

What needs to be a function local variable?

Pretty much everything that is related to the function you are writing needs to be var scoped.

Placing a variable in the var scope

  1. simple variables
<cffunction name="addNumbers" returntype="numeric">
  <cfargument name="b" type="numeric" required="true" />
  <cfset var x = 5 />
  <cfreturn x + arguments.b />
</cffunction>
  1. Loop indexes
<cffunction name="doLoop" returntype="numeric">
  <cfargument name="b" type="numeric" required="true" />
  <cfset var x = 0 />
  <cfset var y = 0 />

  <cfloop index="x" from="1" to="#arguments.b#">
    <cfset y = y + x />
  </cfloop>

  <cfreturn y />
</cffunction>
  1. Query names
<cffunction name="getSomeRecords" access="public" output="false" returntype="query" hint="returns a record set">
  <cfargument name="ID" required="true" type="numeric" hint="Some user ID" />
  <cfset var qRecords = "" />
  <cfquery name="qRecords" datasource="#variables.DSN#">
    SELECT id, label
    FROM someTable
    WHERE id = #arguments.ID#
  </cfquery>
  <cfreturn qRecords />
</cffunction>
  1. the “variable” or “returnVariable” attribute of any CF tag
<cffunction name="readFile" returntype="string">
  <cfargument name="filePath" type="string" required="true" />
  <cfset var fileData = "" />
  <cffile action="read" file="#arguments.filePath#" variable="fileData" />
  <cfreturn fileData />
</cffunction>

Can I var scope anywhere?

If you’ve worked with Javascript for a while, you may have seen the var scope already. Javascript allows you to var scope a variable anywhere in the function.

Javascript function with multiple var scoped variables

function foo(a) {
  var b = 10;

  for (var x = 0; x <= a; x++)
  {
    b = b * a;
  }

  return b;
}

Coldfusion requires that all var scoped variables be declared at the top of the function, after any cfarguments, but before anything else is done.

CFFunction with mutlple var scope variables

<cffunction name="doLoop" returntype="numeric">
  <cfargument name="a" type="numeric" required="true" />
  <cfset var x = 0 />
  <cfset var b = 10 />

  <cfloop index="x" from="1" to="#arguments.a#">
    <cfset b = b + x />
  </cfloop>

  <cfreturn b />
</cffunction>

Can I name a var scoped variable anything?

The only conflict in naming function local variables is that they cannot match any of the argument names for the function.

Invalid var scoped variable name

<cffunction name="doSomthing" access="public" output="false" returntype="string">
  <cfargument name="foo" required="true" type="string" hint="" />
  <cfset var foo = arguments.foo />
  <cfreturn foo />
</cffunction>

But I’ve already written a ton of code . . .

Fear not! Mike Scherberl has written a great tool called varScoper that will scan through your files and tell you which variables need to be var scoped in your existing code base.

Can we talk about specific objects now?

Yes, yes, yes. Now pipe down or I’ll turn this Primer around and we’ll go home.

The first object we’ll discuss tends to spark a few fires in the Coldfusion community: The Gateway Object.

Put on your protective gear and let’s head into the inferno.

About the Author
Adrian J. Moreno

Adrian is an enterprise solution architect and full stack developer. Which stack depends on which system is on fire at the time. More information