ColdFusion Muse

Why Curly is Not Just For Yucks

Mark Kruger February 10, 2009 1:41 PM ColdFusion Comments (13)

Most Muse readers know I'm a fan of Cfscript. I often use it in the sample code as well as in the code I write and demonstrate. I use it frequently for a couple of reasons. One reason is that I have an easier time of commenting with cfscript because I can just add a couple of slashes, type a comment and hit enter. I also like cfscript for working with CFCs. For me the code ends up being more readible. As you probably know you can save a few lines with Cfscript as well. Consider the following example:

<cfif isDefined('url.myvar') AND isNumeric(url.myvar)>
    <cfset myvar2 = url.myvar * 2/>
</cfif>

Inside of a cfscript block this same code would look like this:

<cfscript>
        if(isDefined('url.myvar') AND isNumeric(url.myvar))
            myvar2 = url.myvar * 2;
    
</cfscript>
So a series of validations or sets can be written to conserve space and bring your code together. You might notice something else about the code above. I'm not using curly braces around my "set" statement. The same block of code could be written like this:
<cfscript>
        if(isDefined('url.myvar') AND isNumeric(url.myvar))
            {    myvar2 = url.myvar * 2;        }
    
</cfscript>
...but like most scripting languages, if you leave off the curly braces the code will look for the very next statement on it's own line and execute it as if it were separated by curly braces.
<cfscript>
    if(isDefined('url.myvar') AND isNumeric(url.myvar))
    {    myvar2 = url.myvar * 2;
        myvar3 = 5;
        myvar4 = 0;
    } else
        myvar2 = 0;
</cfscript>
Nice and neat right? Well there is a down side to this approach. I still like it for a big group of validations or checks with sets, but I don't like it so much when combined with a multiline IF (as above).

Let's say someone fiddling with my code above has to add additional sets in the "else" block. Let's also presume that this code is nested one level deep (as is sometimes the case). So the code looks like this:

<cfscript>
    if(runthiscode()) {
        if(isDefined('url.myvar') AND isNumeric(url.myvar))
            {    myvar2 = url.myvar * 2;
                myvar3 = 5;
                myvar4 = 0;
            } else
                myvar2 = 0;
    }
</cfscript>
Even an advanced programmer adding additional sets might do something like this:
<cfscript>
    if(runthiscode()) {
        if(isDefined('url.myvar') AND isNumeric(url.myvar))
            {    myvar2 = url.myvar * 2;
                myvar3 = 5;
                myvar4 = 0;
            } else
                myvar2 = 0;
                myvar3 = 55;
                myvar4 = '';
    }
</cfscript>
And you know - it actually looks nearly right. But ask your self what will happen if "url.myvar" exists and is a number? What will be the outcome? It would be:
myvar2 equals 0
myvar3 equals 55
myvar4 equals '' (blank)
You see what happens? The only statement that is "skipped" in the code above would be the statement immediately underneath the "else". The other 2 statements actually exist outside of the else - even though they look pretty cozy. The proper statement should look like this:
<cfscript>
    if(runthiscode()) {
        if(isDefined('url.myvar') AND isNumeric(url.myvar))
            {    myvar2 = url.myvar * 2;
                myvar3 = 5;
                myvar4 = 0;
            } else {
                myvar2 = 0;
                myvar3 = 55;
                myvar4 = '';
            }
    }
</cfscript>
If the programmer had included curly braces around the original "else" part of the statement then the modification would have worked right out of the gate. As it is, the programmer modifying the code probably spent 15 minutes banging his forehead against the desk crying "Why is myvar3 55??” So the muse rule of thumb is, if you are in an IF/Else block in CFSCRIPT and either of the blocks (the IF or the ELSE) is more than one line - make sure and use curly braces for both of them. You will save yourself and your fellow programmers some grief.

  • Share:

13 Comments

  • Ben Nadel's Gravatar
    Posted By
    Ben Nadel | 2/10/09 12:09 PM
    Good post. I think people should do as much as they can to remove any ambiguity from the code. Now, obviously, the first case it not ambiguous from a run-time standpoint, but it certainly is from a read-time standpoint (people looking at the code). But, I think readtime ambiguity, as you demonstrated, has a cost that far out weighs the saving on a few characters.

    Similar pet peeves of mine:

    People who don't use close-tags or self-closing tags on custom tags:

    <cf_my tag>

    Is that an open tag? Or a tag that has no end mode?? GRRR!
  • Brad Wood's Gravatar
    Posted By
    Brad Wood | 2/10/09 12:10 PM
    I've gotten to where I always use curlys for this exact reason. Sometimes it's annoying becuase I like code to be as clean and little as possible while still being clear and readable. It would probably help if I wasn't so dang anal about having the curlys on their own lines. I always like to visually line up start and end curlies vertically. I would paste an example, but I fear all formatting would be lost. :)
  • Eric Belair's Gravatar
    Posted By
    Eric Belair | 2/10/09 12:22 PM
    For scripting languages, I tend to follow the accepted standard of "if any condition requires more than one line of code, all conditional statements should use curly braces". Generally, I leave curly braces off single ifs (no else) with one line, or use a switch/case if possible, always using curly braces for switch/case.
  • Eric Belair's Gravatar
    Posted By
    Eric Belair | 2/10/09 12:24 PM
    @Ben - I agree. That's why I always close a standalone tag with a slash:

    <cf_mytag />
  • Ben Nadel's Gravatar
    Posted By
    Ben Nadel | 2/10/09 12:26 PM
    Word up! All praise the closing slash !
  • Lyle's Gravatar
    Posted By
    Lyle | 2/10/09 1:37 PM
    The convention I follow is that if it is a one liner, I put it on the same line. If there is an indent, there has to be a curly at the end of the indent.

    <pre>
    if (bob) fun=3;

    ...

    if (jim) {
    fun=1;
    super=2;
    }
    </pre>
    This works for me.
  • Henry Ho's Gravatar
    Posted By
    Henry Ho | 2/10/09 3:39 PM
    If you truly, love cfscript, why use AND? use && ! :)

    btw, closing curly bracket is the suggested style by JSLint.
  • Allen's Gravatar
    Posted By
    Allen | 2/10/09 8:24 PM
    I know everyone has their own approach but my suggestion to avoid this issue is to not only use the curly braces but align them on the left on their own lines. It makes them quite ease to see and clearly delineates a conditional block of code.
  • Matt Williams's Gravatar
    Posted By
    Matt Williams | 2/11/09 5:14 AM
    Just to play the other side of the fence. If you say always put in curly brackets and you put them on their own line, then the tag syntax will always win on number of lines of code. It will be exactly 2 lines less because of the <cfscript></cfscript> tags.

    I'm not saying tags are better than script, but the number of lines argument doesn't really do much to support script.
  • RobG's Gravatar
    Posted By
    RobG | 2/12/09 2:12 PM
    I'm a big fan of properly-formatted code. And one of the things that pisses me off about Java and Javascript is how sloppy people are with their curlies. Example:

    fuction whatever() {
    // whatever
    }

    The OPENING brace belongs on its own line. It's MUCH easier to see at a glance, especially when stuff starts to run together.

    function whatever()
    {
    // whatever
    }

    If you're going to NOT use curlies for a single line after an if or an else, then there should be another line break between that statement and the next:

    if ( whatever )
    a = 0;

    b = 0;
    c = 0;

    And heck while I'm at it, proper indentation should be used to further make it clear what belongs where.

    Am I right?
  • Brad Wood's Gravatar
    Posted By
    Brad Wood | 2/12/09 4:58 PM
    @robG: I don't know if I would go as far as to start labeling "right" and "wrong", but I would definitely say you and me think alike. Sometimes I think we're a minority though. :)

    While we're on this, here's another thing I have started doing. If I am in a bigger chunk of code where the the start and end curly start getting farther apart due to large if statements/loops, I will put a comment after the ending curly to remind me what it ended (event though it is also lined up vertically).

    while (true)
       {
          if(1=2)
             {

             } // end pointless if
       } // end endless while
  • Matt Jones's Gravatar
    Posted By
    Matt Jones | 2/24/09 11:44 AM
    @robG
    i find this:
    fuction whatever() {
    // whatever
    }

    easier to read and comprehend than:
    function whatever()
    {
    // whatever
    }
  • Brad Wood's Gravatar
    Posted By
    Brad Wood | 2/24/09 12:16 PM
    @Matt: Ahh-- so that's where Christine got it from. :)