DEV Community

Michael Born
Michael Born

Posted on • Originally published at michaelborn.me

CFScript Gotchas and Syntax Guides

Now, script syntax is usually straightforward, but as with any language, sometimes it's easy to get confused over certain things in script syntax. In this post I'll cover a quick list of common "gotchas" in CFScript, document the proper syntax for each, and finally link to a list of CFScript guides which may help you start writing CFScript today.

Common "Gotchas" in CFScript

  • Too many pound signs
  • Missing semicolons
  • New operators
  • Assignment instead of equality operator
  • Strict equality operator

Too Many Pound Signs

Don't do this:

if ( #isBroken# ) {
    writeOutput( "Hello #name#!" );
    writeOutput( #age# );
}

Why not? Because the pound signs are only necessary within strings. I suppose the correct term is "string evaluation", because your variable needs to be evaluated and the contents placed within the string.

Here's the proper syntax for that above example:

if ( isBroken ) {
    writeOutput( "Hello #name#!" );
    writeOutput( age );
}

For a more detailed writeup, check out Mark Kruger's "Bamboozled by Pound Sign Decisions" blog post.

Missing Semicolons

This is a fairly easy one. Semicolons are used to terminate a CFScript statement, and are required in ACF up to CF2016. Semicolons are optional now in CF2018, as well as Lucee. So if you get a cryptic "Invalid construct. on line x" error, you may want to check your semicolons!

New Operators

If you're using CFML's JS-like syntax, you should use the new JS-like operators as well, no? This is a matter of preference, but I feel that these operators are more "standard" in all languages and a consistent, improved experience for CF devs.

  • Instead of NOT, use !
  • Instead of EQ, use ==
  • Instead of NEQ, use !=
  • Instead of GT, use >
  • Instead of LT, use <
  • Instead of GTE, use >=
  • Instead of LTE, use <=
  • Instead of OR, use ||
  • Instead of AND, use &&

Older tag-based operators:

if ( NOT json.success OR arrayLen(validation.errors) GT 0 ) {
    // do something
}

Newer, JS-like operators:

if ( !json.success || arrayLen(validation.errors) > 0 ) {
    // do something
}

PS. ArrayLen() always returns a non-negative integer. There's really no need to check that it's greater than zero, because any non-zero integer will evaluate to true in CFML. Whereas zero always evaluates to false. So you can shrink that conditional further like so:

if ( !json.success || arrayLen(validation.errors) ) {
    // do something
}

Using the Assignment Operator Instead of Equality Operator

I feel like this is a rite of passage for all developers. If you accidentally use the assignment operator (=) instead of the equality operator (==) in a conditional, you will get some very interesting results.

For example, this code will always print True! in Lucee.

if ( a = 1 ) {
  writeOutput("True!");
} else {
  writeOutput("False!");
}

That is a tough bug to find, because it looks right upon first scan. So be intentional about how you write your conditionals!

Strict Equality Operator

This is almost trick question - there is no "strict equality" operator in CFML!

So don't do this, because it just won't work:

if ( myVar === "theValue" ) {
    // do something
}

If you must enforce a type, use isValid().

CFScript Syntax Guides

I thought I'd put together a quick (non-exhaustive) list of CFScript syntax guides that may help folks on their journey to modern CF. You may want to bookmark a few of these, like Tony Junkes' comparison of tag and script syntax, as well as Ortus' "100 Minutes" full-on CFScript guide, and finally a cheat sheet by Pete Freitag. As you can see, there is a lot of CFScript documentation out there.

Hope this helps - thank you for reading!

Top comments (0)