ColdFusion Muse

Dynamic Output Evaluation between the Pound Signs

Mark Kruger August 15, 2005 3:17 PM Coldfusion Tips and Techniques Comments (3)

Some developers use the "NOT" keyword in a unique fashion. Instead of only using it inside of a logic statement they take advantage of CFMX dynamic pound sign evaluation features to treat NOT like it is a function. This is misleading. NOT is not a function. It is an Operand that affects the logic of a statement. The only reason it seems like a function is that CFMX servers have a nifty feature that allows for you to put expressions between pound signs in output code. For example, if you put #1+3+5+8# in between cfoutput tags on a CFMX server the result would be the number 17 sent to the output buffer. That's nifty all right, but that's not all.

You could also do the following #(1+3+5+8) is 17# and the result would be the word YES. Notice how the "IF" is implied. The server simply uses looks at the results of the first part and compares it to the results of the second part. The pound signs and the cfoutputs dictate a scalar value be sent to the buffer, so the server sends YES. To illustrate, the following code is valide output in CFMX.

<cfoutput>

<ol>
   <li>#not true#</li>
   <li>#not(true)#</li>
   <li>#1+3+5+8 is 17#</li>
   <li>#(1+3+5+8) is 17#</li>
   <li>#not 1+3+5+8 is 17#</li>
   <li>#not (1+3+5+8 is 17)#</li>
   <li>#not 1+3+5+8 is NOT 16 + 1#</li>
   <li>#not round(1+3.5+5) IS (17+5/2 MOD 4)#   </li>
</ol>
</cfoutput>
If you run this on a CFMX server you will see an ordered list of "YES" and "NO". Notice number 2 and number 6. They might lead you to believe that "NOT" is a function because of the parentheses. The thing to remember is that parenthesis in logic bocks don't necessarily encapsulate arguments to a function. Often they group together statements that must be evaluated as a whole. For example, consider the following:
<cfscript>
   if( (a is b AND c is NOT b) OR (a is c and c is NOT b) )
      ... do something....
</cfscript>
It's clear that the code is looking for 2 separate combinations of a, b and c. The parentheses are used to "group" those combinations.

Where would you use this sort of dynamic evaluation output? Frankly it's not terribly useful - although I have seen some creative uses of it relating to form elements. However, I find it to be slightly bad form. One of the reasons is that your code will be incompatible with previous versions of Coldfusion. The code above will error out in all versions prior to CF. Another reason has to do with the "NOT" key word itself. If you write code like "#NOT(somevar)#" in an output you will leave the impression that NOT() is a function which is not the case. My preference would be to write a function and use it in it's place.

  • Share:

3 Comments


Leave this field empty

Write a comment

If you subscribe, any new posts to this thread will be sent to your email address.

  • Barneyb's Gravatar
    Posted By
    Barneyb | 8/15/05 1:36 PM
    The biggest place I find this useful is in CFQUERYPARAM's NULL attribute:

    <cfqueryparam cfsqltype="cf_sql_integer" value="#myValue#" null="#NOT isNumeric(myValue)#" />

    Same thing for dates. That way you can just pass around a string value (which is either numeric, or non-numeric for NULL), and it will magically be used in your SQL in the correct fashion. The only thing to watch out for is if your DB treats "x = NULL" to ALWAYS be false, even if 'x' is NULL as well. MySQL is this way, though it has a '<=>' operator that is the same as the '=' operator except that two NULL values are considered equal.
  • mark's Gravatar
    Posted By
    mark | 8/15/05 1:38 PM
    Barney - awesome tip. I love that. I'm usually doing some custom function there.
  • ike's Gravatar
    Posted By
    ike | 8/15/05 1:51 PM
    good to know re: mysql ... although I doubt I'll ever use it... I write most of my code to be db-independent (and when I have implemented some not-widely-supoprted features like sequences I'm not using them), so while it would be nice to have a consistent syntax for comparing two columns where nulls are equivalent, it's not likely to be much help in my case... I just wish the db manufacturers would take a hint (or four) from the sluggish browser community which is just now in the pre-natal stages of decent support of standards.

    As to the other, I always use null="#yesnoformat(not isDate(thevalue))#" even when I don't have to because I consider it a best practice (better form) to not have unbound spaces between pound symbols... in the end it may just be personal preference, but then I scarcely ever am writing out my cfqueryparam tags anyway. I have generic db tools that write the cfqueryparam tags for me so that where I might otherwise be writing out pages and pages of cfqueryparam tags, I just put <cfset request.tapi.sql.update("mytable",arguments)>.