A valid use for the Evaluate() Function?

{ Posted By : Eric Cobb on December 10, 2009 }
1019 Views
Related Categories: CFML

In the comments to my recent Rookie Mistakes post, Paul mentions that he is using Evaluate() to get the value of variables stored in a database. In this particular case, he's not storing the variable values in the DB, he's storing the actual variable names and then using Evaluate() to get their values via CF. To be specific he's storing a formula in the DB, and then using Evaluate() to perform the calculation and get the values.

Here's an example of Paul's situation:
<!--- set the variable values --->
<cfset variables.var1 = 2>
<cfset variables.var2 = 9>
<cfset variables.var3 = 3>
<!--- This is the record that would be stored in the DB --->
<cfset variables.var4 = "(variables.var1 * variables.var2) / variables.var3">

<!--- lets fake a DB call. --->
<cfset variables.myQry = QueryNew("varString","VarChar")>
<cfset QueryAddRow(variables.myQry)>
<cfset QuerySetCell(variables.myQry, "varString", variables.var4, 1)>

<!--- Dump our query. --->
<cfdump var="#variables.myQry#">

The result of the dump would be:

So now let's output our query result and try to perform the calculation to determine the value of the formula:
<cfoutput query="variables.myQry">
    #variables.myQry.varString#<br />
    #Evaluate(variables.myQry.varString)#<br />
</cfoutput>
This would give us
(variables.var1 * variables.var2) / variables.var3
6

As you can see, outputting the variables normally just outputs the string stored in the DB, while the Evaluate() function translates the variables into their actual values, "(2 * 9) / 3", and then performs the calculation with no problem. Also if we try to do this using array syntax instead of Evaluate(), we still get the literal string that was stored in the DB.

<cfoutput query="variables.myQry">
    #variables.myQry["varString"][variables.myQry.CurrentRow]#<br />
</cfoutput>
Returns:
(variables.var1 * variables.var2) / variables.var3
Again, if we wrap that in Evaluate, it processes the variable values:
#Evaluate(variables.myQry["varString"][variables.myQry.CurrentRow])#
Returns:
6

I played around with different variations of the output, and so far I have not been able to find a way to do this without using Evaluate(). I even spent some time trying to uncover what Java was doing under the hood with Evaluate(). In the end, I came up empty handed. My gut tells me that even if we went the Java route, it would wind up being more code and more cumbersome than just wrapping the variables in Evaluate().

So, my conclusion is this: This is a good use for Evaluate(). This is one of the rare cases when using Evaluate() is the right (only?) way to accomplish the desired results. If there's anyone out there that knows how to accomplish this without using Evaluate(), or a ton of extra coding, I would love to see it!

Related Blog Entries

Comments
Ben Nadel's Gravatar Other than writing the variable to a file and then CFInclude'ing it (such as from the ram:// disk), I cannot think of any way to do this without using Evaluate().
# Posted By Ben Nadel | 12/11/09 2:45 PM
Eric Cobb's Gravatar Thanks, Ben. I'm glad to know that it wasn't just me! I was afraid this was something simple and obvious staring me in the face and I was just over complicating things and couldn't see it!
# Posted By Eric Cobb | 12/11/09 3:27 PM
Andy K's Gravatar It's worth noting that the Evaluate function is not the pariah that it once was in terms of performance. While array notation ought to be used as a best practice when possible, I would not fret over using Evaluate()...
# Posted By Andy K | 12/11/09 6:14 PM
Ben Nadel's Gravatar @Andy,

This is very true. My general dislike of Evaluate() is not a performance issue, but rather that I always felt it represented a misunderstanding of how variables could be accessed in ColdFusion. But, that's just a personal issue :)
# Posted By Ben Nadel | 12/13/09 10:21 AM
Paul S.'s Gravatar @Ben - hello and thanks for the input. reading your comments I couldn't tell if you felt the methodology I was using was an acceptable practice or if I should be looking at an alternate solution?
# Posted By Paul S. | 12/14/09 10:05 AM
Ben Nadel's Gravatar @Paul,

When I can, I prefer to use a non-Evaluate() methodology. But, sometimes, as in this case, Evaluate() is the right choice.
# Posted By Ben Nadel | 12/14/09 10:39 AM