Welcome!

ColdFusion Authors: Pat Romanski, Liz McMillan, Maureen O'Gara, Greg Ness, Andreas Grabner

Related Topics: ColdFusion

ColdFusion: Article

Worst Practices

Worst Practices

"If debugging is the art of taking bugs out of programs, programming must be the art of putting them in." -Anonymous

I've been hard at work creating material for a "Best Practices with ColdFusion & Fusebox" training class and it got me thinking: Why don't we ever see a worst practices class? Heaven knows there are some real stinkers out there - why aren't they shared with others, so that all may learn? If something's worth doing badly, isn't it worth doing really badly? Or, as one of the regulars on the Fusebox list notes in his signature line: amateurs built the Ark; professionals built the Titanic.

Yet, as I look about, all I see are people working on improving code. Go to Figleaf's site, for example (www.figleaf.com). What do you find? Lots of stuff made to help coders become better coders: code samples, presentations, and more.

Or go to www.fusebox.org - same thing - lots of stuff to help people write better code. My friend, Adam Churvis, is practically giving products away to help developers at www.commerceblocks.com.

And, loath as I am to confess it, even I am not blameless; www.halhelms.com has tutorials and even free online classes all designed to - you guessed it - help developers write better code.

Now writing good code is fine - if that's what you want to do. However, from looking at some code, I'm not convinced that's what people want to do. For example, here's a bit of code that, I swear, came from a production environment:

<cfloop
from="1" to="#ListLen(Trim(ValueList(myQuery.Name)))#"
index="i">
#ListGetAt(ValueList(myQ.Name),i)#<br>
</cfloop>
Can anyone argue that the coder was trying to write good code? I think not. The programmer looking to write good code would probably have chosen, instead, something more mundane:
<cfoutput query="myQ"> #name#
</cfoutput>

I think you'd agree the first snippet is far more... far more... how shall I put it?

Bad. In fact, it's so bad, so amazingly, needlessly complex, that for it to lie in obscurity forgotten seems terribly wrong. Surely if anything does, this code calls out for a Worst Practices award.

I've found that there are three main reactions to code such as this. The first and most common reaction is despair. "I can never aspire to this level of incompetence," you say. That's a natural reaction. But I'm here to tell you: you really can be that bad - but you'll need some help. Help that I never received. In looking over some of my own early code, I can see in retrospect that I showed real promise. I can only wonder how far I might have gone had this early flicker of potential not been snuffed out by exposure to really good programmers.

The next reaction to the code sample above is cockiness. "I could write bad code like that standing on my head in a snowstorm." No, you could not, and remember, Worst Practices code is not just "bad code." Although a proper analysis must be left to another time, suffice it to say that just as taking scissors to a normal painting and rearranging the resulting parts won't yield a Picasso, neither will ignoring best practices produce true Worst Practices code. Although it's a start.

The final reaction comes from the person who says, "But of what use is Worst Practices code?" And I say, "Of what use is a mountain, or a sunset?" Some things are just for their own sake.

So in the hopes that you fickle readers will remember this community service when next year's CFDJ awards roll around, I offer you this free (for now) Top Ten List of Worst Practices for your nonedification.

1. Using creative naming schemes
Anyone determined to master Worst Practices code will start here. The would-be Worst Practices programmer will find all sorts of ways to make his or her code obscure and unreadable. And maintainability? Hello?

Here are some examples:

  • variable_with_liberal_use_of_ underscores: Much to be desired for the way it causes the programmer to use a two-key combination to create the underscore. And since most programmers can't find the underscore key by touch, they have to stop and look at the keyboard. A nice touch.
  • pro_id: Note here the abbreviation pro. Does this stand for product? Project? Program? Something else entirely? Who knows - certainly not the person who has to maintain this code. Score one for Worst Practices and use abbreviations liberally in your code.
  • Equals as a variable name: For this inspired bit of advice I must give credit to Roedy Green (whose brilliant site at www.mindprod.com/ unmain.html provides tips that should be studied by all aspirants to the Worst Practices Hall of Fame). Imagine the code you can write using equals.
    <cfif equals GT 10>
    That should keep them guessing for a while.
  • amadeus: Yes, this old chestnut should not be forgotten. Use whimsical names for variables in order to keep the "fun" in programming. Amadeus is my cat's name, but you should feel free to use whatever you're interested in.

There are so many more, but I must move on to...

2. Commenting your code
Of course, it's best not to comment your code at all, but you may find that due to political pressures, you must provide some level of comments. Still that doesn't mean you have to like it, so why not let your displeasure show in the way you write comments? Here's some code I found...

<!--- Loop over the fields in the form. If any of them match a cookie that was set previously, user wants to make a substitution. This will go in "substitutions" that will be passed on.--->
<cfloop list="#form.fieldnames#" index="aField">
<cfif IsDefined( 'cookies.' & i )>
<cfset substitutions = ListAppend( substitutions, aField )>
</cfif>
</cfloop>
Note how the comments tell why the code executes rather than how it executes? This is the hallmark of good comments. What can I say? This coder just doesn't "get it." Now look at my reworked Worst Practices code:
<!--- Loop over list. If a list item matches a cookie, put list item in another list. --->
<cfset amadeus = form.fieldnames>
<cfloop list="#amadeus#" index="i">
<cfif IsDefined( 'cookies.' & i )>
<cfset ludwig = ListAppend( ludwig, i )>
</cfif> </cfloop>

All the comments are entirely trivial. They indicate nothing that a cursory glance at the code won't reveal, while the meaning of the code is impossible to discern. Admittedly, it isn't easy to get to this level of obscurity, but it's certainly something to strive for.

In Louisiana they use the word lagniappe to describe "a little something extra." There's a lagniappe in the converted code. Do you see it? It's the use of i as the variable name for an index. This was originally used in languages whose loops only gave you a handle on the integer value of each element as it was being looped over. You started with 0 and then worked your way through the number of times looped. But with ColdFusion you have a handle on the actual value in the list itself. You can see in the original the misguided coder uses the term aField to describe... well, a field. I think you'll agree my code is far less clear.

3. Duplicate functionality
If something's worth writing, it's worth writing twice. Or three times. Or more. That's the motto of the Worst Practices coder.

Here's some "unimproved code":

<cfmodule
template="GetStateTax.cfm"
state="#form.state#"
total="#subTotal#"
returnValue = "stateTax">
<cfset total = subTotal + stateTax + shipping>
The coder created a module to return the state tax for any state. This module can then be used wherever the application needs it. It can also be used by other applications as it's generic. But all those words! Look how much "simpler" the Worst Practices code is:
<cfset total = subTotal + subTotal*0.85 + shipping>

Now, when the state tax rate changes, you'll have to search through every file that might be affected. Using the unimproved version, you'd only have to make a change to a single file.

You are taking notes, aren't you? Okay, then let's move on to...

4. Don't use third-party code!
The Allaire Developer's Exchange (http://devex.allaire.com/developer/ gallery/) is full of code that others have sweated over and debugged. Do you honestly think a Worst Practices coder would use such a thing? Please...

Let's say you need to sort a two-dimensional array, something that ColdFusion has no built-in function for. If you immediately thought, "I'll bet there's a tag for that!" slap yourself! Of course someone has already written a tag for it. What's that got to do with anything? Surely if you're willing to write your own code twice (see Tip 3), you should be willing to duplicate code someone else has written. I hope that's clear.

5. Use global variables - a lot!
One of the more important Worst Practices is using global variables liberally. You never know when you might need a piece of information. Best to make it global! At first glance it might not appear self- evident why this should be a Worst Practice, but consider that as a program's number of moving pieces increases, global variables are like landmines, hidden from view. There's no telling when someone paying attention to this tip will accidentally overwrite one that you wrote - and then the fun begins in earnest!

6. Don't use assertions to test variables
There's a whole class of errors that occur because code is expecting a variable of a certain type or its value lies within certain bounds. Consider this code:

Thanks to our FriendlyShopper(tm), your shipping works out to only $#Val( shippingCost/packageQuantity )# per package. Such a deal!

This works fine until you get a packageQuantity of zero, then your user receives a little lesson in the impossibilities of division by zero. The ColdFusion tag, <cfparam>, offers some rudimentary protection against such types of errors.

Recently I wrote a column on assertions (as such error protections are often called) in CFDJ (Vol. 2, issue 10) that provided a custom tag for implementing assertions in ColdFusion. Avoid it.

7. Error handling is for others
Exception and error handling is based on the notion that something unexpected can occur. But is this notion really true? To our code?

Still not convinced? Tell you what, let's do it "later," okay?

8. Testing is for losers
I'm sorry to be so harsh here, but sometimes the cold truth is called for. Testing code is an implicit admission that your code might not measure up. Is that the message you want to give to others, that you're not good enough?

When people report "anomalies" in the code, the savvy Worst Practices coder demands to know every detail about the alleged "error," including:

  • Time of day
  • Exactly what were the last 100 keystrokes that were pressed immediately prior to the condition (a much better word)
  • What operating system the user was running. Were all service packs installed? When were they installed?
  • Other applications on the user's disk (whether running or not at the time)
  • Whether AOL was involved
  • Whether any aurora borealis activity was present in the user's region
  • Whether the user can spell aurora borealis
You get the point, I think. Some wise man once pointed out that one way to reduce the crime rate is to make theft legal. I call this "thinking outside the box." It's also true that one way to eliminate errors is to make dental surgery preferable to reporting them. No reports, no errors. Sometimes, simple is better.

9. Avoid JavaScript for form validation
Despite Selene Bainum's excellent article in the August 2000 issue of CFDJ (Vol. 2, issue 8), explaining how simple it is to use JavaScript and together, Worst Practices coders are adamant about avoiding JavaScript for form validation. It smacks too much of assertions and code testing.

If you can't avoid form validation entirely, at least do it on the server with ColdFusion. That way the user will have to wait for the round-trip to the server and back. Consider it a very gentle rap on the user's knuckles. Maybe next time they'll be a little more careful and figure out that when you asked for their phone number, you wanted it in the format 555-555-5555, not (555) 555-5555.

Granted, you didn't tell them this, but a Worst Practices coder isn't really into that touchy-feely user-interactivity thing. Leave that for the losers who test their code.

10. Mentor others
Worst Practices coders know that they must "give back" to the Worst Practices community. They do so by teaching others these techniques and thus help to swell the ranks of Worst Practices coders. But, if I may wax philosophical for a moment, tips like these aren't enough. Coders - especially junior coders - are eager to do good work. They're likely to want to do such things as attend classes, read books, and discuss new ideas and new ways of doing things.

In this context "mentoring others" means crushing all enthusiasm by applying generous doses of sarcasm, stony silence, and implications that "real coders" don't worry about/need that stuff. Worst Practices coders remember how "helpful" their bosses were, and once they get into a position of power, they follow the Biblical injunction to "go and do likewise."

Sadly, our tour of Worst Practices must end. I'd like to close with a quote from the great American cowboy-philosopher, Will Rogers, who might well have been talking about this very subject when he said, "If stupidity got us into this mess, then why can't it get us out?" I'd like to think that this column has pointed a way in that very direction.

More Stories By Hal Helms

Hal Helms is a well-known speaker/writer/strategist on software development issues. He holds training sessions on Java, ColdFusion, and software development processes. He authors a popular monthly newsletter series. For more information, contact him at hal (at) halhelms.com or see his website, www.halhelms.com.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.