<<

Decision Making and Scopes

Decision Making

By Nic Tunney (Bio)
gist

An important part of any program is the ability to make decisions based upon a set of conditions. This is aptly named 'conditional logic'. Unless you are writing a static set of HTML pages, you will almost certainly need to evaluate conditions. In conditional logic, all conditions tested must evaluate to a Boolean, either true or false. As you learned in the variables section of this training, ColdFusion is a dynamically typed language. This does not mean that ColdFusion is not typed, but rather that ColdFusion can switch from type to type dynamically while the application is executing. This is a great feature when using conditional logic as you do not need to explicitly define the Boolean such as myVar == true, but for simple variables you can allow ColdFusion to evaluate the value of the variable and convert it dynamically to a Boolean value. Keep this in mind, and we will revisit this in a bit.

ColdFusion has both if/then/else tags as well as switch/case logic. We will look at if/then/else logic first. There are three tags that are important when evaluating conditions: cfif, cfelseif, and cfelse.

cfif is used to start a decision block. As with any properly formed tag block, being XHTML compliant, a cfif block is terminated with . Inside the conditional block you will place either code to execute or markup to output. A simple case looks like this:

<cfif expression>
	..Markup..
</cfif>

The decision block above says that if the expression evaluates to true, then execute the tag contents. If the expression evaluates to false, do nothing. However, if we want it to do something if the expression evaluates to false, we use the cfelse tag like this:

<cfif expression>
	..Markup..
<cfelse>
	..More Markup..
</cfif>

If you need to compare several conditions in succession, use cfelseif:

<cfif expression>
	..Markup..
<cfelseif another_expression>
	..More Markup..
<cfelse>
	..More Markup..
</cfif>

For review, an expression is any value that will evaluate to a Boolean (true or false). You can provide a string value that will evaluate to a Boolean such as a number. Any positive number will evaluate to true; 0 evaluates to false. Negative numbers evaluate to false as well. You may also call a function that returns a Boolean or numeric value like these:

len(myStringVar); // returns a number
isNull(mySimpleVar); // returns a Boolean
arrayLen(myArray); // returns a number

Sometimes you will need to perform a values comparison. ColdFusion includes many decision operators, all of the following being case-insensitive.

CFML and CFScript Operators CF8+ CFScript Only
IS, EQUAL, EQ ==
IS NOT, NOT EQUAL, NEQ !=
GT, GREATER THAN, LT, LESS THAN, GTE, LTE >,<,>=,<=
CONTAINS N/A
DOES NOT CONTAIN N/A

These operators allow you to compare a set of values. An example in action is:

<cfif myValue EQ 'ColdFusion'>
	..code…
</cfif>

Below is a fully formed example of a script based if/then/else block. Since ColdFusion is ECMAScript compliant, it should look very familiar:

if (myValue == 'ColdFusion') {
	..code..
} else if (myValue != '.NET') {
	x = 277;
} else {
	..code..
}

There are also times you will want to compare more than one expression. ColdFusion provides a series of Boolean operators to permit join and negation operations:

AND / &&
OR / ||
NOT / !
XOR, EQV
IMP - implication

An example of a compound expression looks like this:

<cfif structKeyExists(myStruct, 'age') AND myStruct.age LTE 7>
	..code..
</cfif>

The important thing to know about compound expressions is that ColdFusion will move from left to right when processing joined expressions. The example above first checks to make sure the age key exists in the structure called myStruct before performing further operations on it. If we check the value of the key and the key is not defined, ColdFusion will throw an error. Since ColdFusion works from left to right, ColdFusion would first see that age does not exist as a key in myStruct (structKeyExists will return false) and it will not perform the second operation. This is not the case for OR operations. Look at the following example:

<cfif myVar EQ 1 OR myVar EQ 10>
	..code..
</cfif>

ColdFusion would look first at myVar EQ 1. If it returned false, it would simply move on to evaluate the second expression. In this case, if our variable was equal to 1 or 10, the code inside the cfif block would be evaluated.

In the example above, we are checking if a variable is equal to a set value. When programming, if/then/else logic can become cumbersome when you need to perform an action based on a variable's value. Programming languages use the switch/case construct for this type of conditional logic. ColdFusion uses 3 tags to define switch/case statement: cfswitch, cfcase, and cfdefaultcase. Look at the sample code below:

<cfswitch expression="#myVar#">
	<cfcase value="1">
		..code..
	</cfcase>
	<cfcase value="9,10" >
		..code..
	</cfcase>
	<cfdefaultcase>
		..finally..
	</cfdefaultcase>
</cfswitch>

The code above defines a switch block based on the expression of the value of myVar. Note that we are using hash marks (#) here as the expression attribute, taking a string value, and comparing it to a set of possible matching values. The possible values are each defined in their own cfcase block. cfcase takes a string attribute named value, and if it matches the current value, it will execute the code contained inside of the cfcase block. A value may only be declared once within the entire switch block or ColdFusion will throw an error. cfswitch will work from top to bottom to find the first matching value. If it cannot find a matching value, it will execute the code contained inside of the cfdefaultcase block. It is not required to have a cfdefaultcase block defined, but your logic will dictate if it is present.

The second cfcase declaration above lists more than one value. If the expression is either 9 OR 10, the code will execute. The default delimiter is ','. If the value contains a comma, it is automatically treated as a list. If you want the value to include a comma in the string, simply specify an alternate delimiter using the delimiters attribute like this:

<cfcase value="9,10" delimiters="|">
	..code..
</cfcase>

This will allow the comparison value to be a string of 4 characters "9,10".

Astute programmers may have noticed we have not had to define a break for each case. This is true in tag based CFML switch/case statements. In cfscript, you will need to use the break statement as with any other programming language. Here is an example of a switch case construct in cfscript:

switch (myVar) {
	case 1:
		writeOutput('Value was 1');
		break;
	case 9:
		writeOutput('Value was 9');
		break;
	default:
		writeOutput('Value was not 1 or 9');
}

ColdFusion also offers ternary operations. A ternary operation is a construct that acts as a shorthand assignment operation given a comparison with exactly two possible outputs. Here is an example in cfscript:

x = (myVar == 1) ? 1 : 277;

The above is equivalent to saying:

if (myVar == 1) {
	x = 1;
} else {
	x = 277;
}