CFML 101 - Rookie Mistakes Part 1
This is the first in what I hope to be a continuing series of CFML 101 articles. My intent is to produce a blog series aimed at the beginning CFML developer, one which helps to explain basic techniques and concepts to those new to the CF world. The topics and examples covered in this series focus on the CFML programming language in general, not a specific application server. So whether you're using ColdFusion, Railo, or Blue Dragon (referred to as CF/R/BD from this point forward) to run your CFML applications, these concepts still apply.
The first post covers rookie mistakes that we've all done at one point or another. These are things that seasoned developers instinctively know to do, but beginners may not realize are better or more efficient. Much of this post is based loosely on Adobe's Coding Best Practices for ColdFusion Performance, with a few of my own personal favorites thrown in there.
1) Drop those pounds!
This is probably the most common rookie mistake out there, the over-use of pound signs ("#", "number sign", "hash symbol", "octothorp", etc...). This is always a tell-tale sign of a n00b CFML developer. Not that there's anything terribly wrong with it, I had been coding this way for about 2 years before I realized that you shouldn't do it. For most beginning developers this an easy one to miss, because your code seems to be running fine and you don't realize that it actually negatively affects performance.
Here are a few examples of the over-use of pound signs:
<cfset foo = #trim(bar())#>
<cfif "#trim(myName)#" eq "Eric">
While the above examples will work fine, the following examples of the same code are simpler and more efficient:
<cfset foo = trim(bar())>
<cfif trim(myName) eq "Eric">
One of the few times you need pound signs inside of a CFML tag itself is for a tag's attribute. Here are some examples of when you would use pound signs inside of a tag.
<cfhttp path="#myPath#">
<cfquery datasource="#DSN#">
Please not that I am talking about the content inside of the tag itself, not the content between the opening and closing CFML tags.
2) Too many cfoutputs!
Another tell-tale sign of a n00b CFML developer is surrounding every variable with cfoutput tags. Take the following example:
<input type="hidden" name="val1" value="<cfouput>#val1#</cfoutput>" />
<input type="hidden" name="val2" value="<cfouput>#val2#</cfoutput>" />
<input type="hidden" name="val3" value="<cfouput>#val3#</cfoutput>" />
<input type="hidden" name="val4" value="<cfouput>#val4#</cfoutput>" />
</form>
While the above code will work fine it causes your CF/R/BD server to have to work harder, and let's face, no one likes to work harder than they have to. When your server has to work harder, it negatively affects performance. Using unnecessary cfoutput tags can be equated to turning your car on and off at every traffic light, stop sign, and intersection. There's no point in turning your "output" on and off constantly throughout your page. This example is much simpler and more efficient:
<cfoutput>
<input type="hidden" name="val1" value="#val1#" />
<input type="hidden" name="val2" value="#val2#" />
<input type="hidden" name="val3" value="#val3#" />
<input type="hidden" name="val4" value="#val4#" />
</cfoutput>
</form>
As a general rule, you should try to have as few cfoutput tags on your page as possible.
3) Whose variable is this?
You should always, always, always, always scope every variable in your CFML applications. Do it. Every time. Always. No Exceptions. Got it? ESPECIALLY in your CFCs. (For those that don't know, "scoping" a variable means providing a prefix that designates where the variable belongs, I.E. "form", "url", "request".)
The Adobe article mentioned above specifically states in its first item:
"You can improve performance by always qualifying your variables with the proper scope. Wherever possible use fully scoped variables. A variable that has a scope prefix will be evaluated quicker than an unscoped variable."
To elaborate on that, here is the order of precedence that is used to determine a variable's scope.
- Query Results
- Arguments
- Variables
- CGI variables
- File variables
- URL variables
- Form variables
- Cookie variables
- Client variables
For example, if you have the following set statement:
Every time you reference the variable "myName" CF/R/BD will do the following:
- I don't know where "myName" came from.
- Is it in a Query? No.
- Is it an Argument? No.
- Is it in the Variables scope? Yep, found it.
- Process the "variables.myName" variable.
So, that may not seem so bad to start with, CF/R/BD only had to check 3 places before it found where we put "myName". (for those that don't know, a variable created using a cfset tag automatically gets put in the "Variables" scope unless otherwise specified). But what if you referenced "myName" 10 time in your CMFL page? That's 30 checks. What if you have 10 other variables that you set the same way and they each get referenced 10 times? Yeah, the checks start to add up, don't they?
Now, what if you have a form that has an input box named "myName" in it, and when you submit the form you don't specify a scope in your form handler code? Now CF/R/BD has to do the following:
- I don't know where "myName" came from.
- Is it in a Query? No.
- Is it an Argument? No.
- Is it in the Variables scope? No.
- Is it in the CGI scope? No.
- Is it in the File scope? No.
- Is it in the URL scope? No.
- Is it in the Form scope? Yep, found it.
- Process the "form.myName" variable.
So, yeah, scoping variables is important in CFML. You should do it. Every time. Always.
4) Your Evaluation isn't good!
Don't use the Evaluate() function. It's bad. It also has a negative impact on performance. I wish it would go away. I've been coding in CF since version 4.0, and I really can't recall a single time that I've ever used Evaluate(). Something about it just seems dirty to me. I think it's a cheat that keeps people from learning how to code CFML effectively.
According to Adobe, instead of using:
You should use:
Now, I've heard people claim that sometimes you have to use Evaluate() and there's no way around it, but I've yet to come across it. (Now that I've said that I'll probably have to use it tomorrow!). Since ColdFusion MX (which came out in 2003, I think?) all variables scopes can be treated as structures, which means that Evaluate() is pretty much useless, and really just hanging around for backwards compatibility anyway. Ditch it!
And, that's it for this episode. Be sure to tune in next time when we discuss such intriguing topics as, "Where's my Honey-do list?" and "Fun with Functions!"
* This code sample was copied from Adobe's "Coding Best Practices for ColdFusion Performance" article mentioned at the beginning of this post.


@Russ - I hear ya. Even when I pull up some of my old code I think "Aw, man. Now I've got to go fix all of those."
@Gary - yeah, evaluate() is one of those that's easy to miss. Nothing in the livedocs says "there's a better way", even though Adobe recommends not using it.
since the formula can change depending on what we are trying to do.
but we use the same variables to calculate our result.
we use this for a dashboard application for showing the monthly status of a metric. trends can be upwards(greater than 90, within a range, or way off) or downwards (less than 10 percent, within a range or way off. and the calculation determines whether the trend is in the green, yellow or red. our need was to be able to change the trend ranges for each metric to be being charted.
I do use Evaluate quite a bit though - the only main reason for me using it, is to shorten my code. For example say you have 10 HTML input fields and you need to fill the field values from database. Rather than cutting and pasting 10 times and change the field name etc2 - I create a list of the field names and inside the loop I do Evaluate to get the corresponding value from the database to fill the fields value.
Not sure whether this is a good practice - but it does save me from mind numbing cut and paste.
<cfset field_list = 'field1,field2,field3'>
<cfloop list="#variables.field_list#" index="x">
<cfset foo = qry_name["#x#"]>
</cfloop>
So, it looks like you have actually found a valid use for evaluate()! ;^)
thanks, for thinking about possible alternatives to my solution.