If you want to greatly vex the Muse and his merry band of developers, all you have to do is send them sample code with a liberal sprinkling of superfluous pound signs and cfoutputs. ColdFusion is a very forgiving language, so you are free to do all sorts of nails-on-the-chalkboard things that make me cringe - and you will get away with it too. I began thinking about this topic because I'm privileged in my current work to review code created by others. This is double edged sword of course. It's easy to sit back and be cheeky about someone else's approach when you are in the "expert" seat. Still, I have recently reviewed code from more than 10 different developers. I've come to the conclusion that many (perhaps most) sort of guess at when to use pound signs. Once they figure out the approaches that work they stick with that.
The result is that pound signs are like Tribbles on the star trek enterprise. They are fairly innocuous but they annoying show up everywhere. So... having never seen a definitive post on the topic I thought I would jump in and put my stamp on when to use and when not to use pound signs. That's right; the Muse is not making room for other opinions this time. I'm going to lay down the law! So put your seat belts on 'cause it's going to be a bumpy ride.
So the first thing to know is that there are conditions that always require pound signs. To understand this let me introduce you to the concept of the "output buffer". I've not heard a lot of folks talk about this and there may be other monikers for it, but the Muse has adopted "output buffer" so that's what we are going with. Consider the following dialogue between ColdFusion and your request.
This silly little dialogue illustrates the old "output buffer" idea. ColdFusion assumes by default that your request will result in output. It's a web server platform after all. So each request starts with an empty buffer. As things happen in a request the content of the buffer is populated with the results of your work.
It may not be obvious at first, but you can manage this buffer. If you have good code separation where you do all your component calls and heavy lifting first you can bracket your controller code like this:
Now that I have you thinking about the output buffer let's get back to our pound signs. Here's my first rule:This is the first most obvious rule. It's also never broken because breaking it generates errors or means that you don't get what you want on the page. But it's important to state it because it tells you exactly what 99% of pound signs are used for. They are used for outputting variables to be seen by the user. If you remember that one single rule then you will likely not fall into some of the traps I'm about to lay out for you.
This is the one that's violated constantly. You don't need pound signs inside of CFIF statements or inside of cfset statements or to use a variable in a function (although you may need them outside the function if the results of the function are intended as output).
If you tried to use pound signs it would throw an error so this one is never violated. It does, however illustrate a little inconsistency since pound signs are needed for tags in other places as we shall see. In any case, query names are used with no pound signs inside of tags - like so:
CFLOOP is one of those areas where pound signs don't feel like they should be needed, but in fact they usually are. Take arrays as an example. You can't do Array="arrLoop". Instead you have to do Array="#arrLoop#". Collections (used for objects or structs) suffer the same fate. Doing Collection="MyCollection" is incorrect. Instead you have to do Collection="#myCollection#". I'm sure this probably has to do with by reference / by value type decision making under the hood.
Ok.. the muse will give some leeway here. When I concatenate a string with variables I tend to do the following:
When working with a ColdFusion tag (not logic or evaluation or assignment) you are usually going to need the pound sign to pass in values. Here are 2 good examples.
CFSWITCH: When using cfswitch the "expression" is expecting a primitive value (a string, number, etc) for comparison. So it needs the contents of the variable - not the variable name or reference. So this would be correct:
CFMAIL: Another example, Cfmail, requires pound signs around variables except for query (see the Query Rule). This leads to an odd result when working with a query. The name of the query is not bracketed by pound signs while columns from the query must be bracketed. This makes sense if you think of a query driven cfmail as version of a query driven cfoutput. So this would NOT be correct:
So again the variables passed into a tag need pound signs. Look at it closely and you can see why. The "From" and "To" attributes also take a string. How is the tag to discern that a string is a column name? The only way it could would be to force the "to" and "from" address in a query driven cfmail tag to be required to be a column - and of course that would severely limit the use of the tag. Other tags like Cfchart, cfftp, cfschedule, cfzip, cffile etc - all require pound signs when a variable is passed in.
I guess if I had something I would like folks to get out of this post it is to stop using pound signs "when in doubt". Now Muse readers, feel free to set me straight, but let's keep those comments clean and civil.