The Cure for CFIF/CFELSEIF Hell

Posted: December 5, 2007 in ColdFusion
Tags:

Hello World,

Here’s an alternative to those complex CFif/CFelseif statements in your ColdFusion code.

Problem:

Today I was working on a portion of a web site that required the system to perform certain functions based on the existence or non-existence of data in four different variables. Since there are four variables involved in this equation that means that there are 16 different combinations (check my math, please). I think you can imagine the nightmarish nested CFif/CFelseif monster statement that can be constructed from such possibilities.

Solution:

My first step was to map out all of the possible combinations by creating what I call a logic matrix. I was simply a worksheet with each of the four variables listed across the top. Down the rows I shaded the cells that would contain a value in each of the combinations.

I then gave each column a number; 1, 2, 4, 8. i wanted to follow binary numbering to insure that the sum of each row is unique.

I then analyzed each row and determined what process would occur for each combination. Take a look at my screenshot to get an idea of what I mean.

my logic matrix

At this point I am ready to implement my code!

First, I created a CFC function that takes a string variable and it numeric value. The function evaluates the string value to determine if it’s empty or not. Should the string variable be empty a zero value it returned. However should the string variable be non-blank the passed-in numeric value is returned. Take a look at the code shown below:

<cffunction name="evalStringToNumber" access="private" output="false" returntype="numeric">
	<cfargument name="myStrVal" type="string" required="yes">
	<cfargument name="myResVal" type="numeric" required="yes">

	<cfset result = 0>

	<cfscript>
		if(Len(Trim(Arguments.myStrVal)) GT 0) {
			result = Arguments.myResVal;
		}
	</cfscript>

	<cfreturn result>
</cffunction>

Now on to the calling function!This is the main function that takes the four variables and will return a string indicating the process to run. First take a look at the code below:

<cffunction name="doSomething" access="public" output="false" returntype="string">
    <cfargument name="valOne" type="string" required="yes">
    <cfargument name="valTwo" type="string" required="yes">
    <cfargument name="valThree" type="string" required="yes">
    <cfargument name="valFour" type="string" required="yes">

    <cfset processToComplete = "">

    <cfset total =    evalStringToNumber(Arguments.valOne, 1) +
                    evalStringToNumber(Arguments.valTwo, 2) +
                    evalStringToNumber(Arguments.valThree, 4) +
                    evalStringToNumber(Arguments.valFour, 8)>

    <cfswitch expression="#total#">
        <cfcase value="15,14,12" delimiters=",">
            <cfset processToComple = "Process 1">
        </cfcase>
        <cfcase value="11,9" delimiters=",">
            <cfset processToComple = "Process 2">
        </cfcase>
        <cfcase value="4,13,5" delimiters=",">
            <cfset processToComple = "Process 3">
        </cfcase>
        <cfcase value="7" delimiters=",">
            <cfset processToComple = "Process 4">
        </cfcase>
        <cfcase value="6" delimiters=",">
            <cfset processToComple = "Process 5">
        </cfcase>
        <cfcase value="3,1" delimiters=",">
            <cfset processToComple = "Process 6">
        </cfcase>
        <cfcase value="0" delimiters=",">
            <cfset processToComple = "Do Nothing">
        </cfcase>
    </cfswitch>

    <cfreturn processToComplete>
</cffunction>

This function can work any way you want but the two most important aspects of this function are;Calling the evalStringToNumber function, passing it the variable, and its numerical value. Remember that logic matrix? Look across (or imagine) the top row containing your variable names and use the numbers you wrote for each of them. The CFSET variable assignment will sum the value of each of the evalStringToNumber function calls.Now construct your CFSWITCH/CFCASE statement to contain all the different processes that will be called based on the value of total. Each combination on the worksheet should correspond to a CFCASE statement.An that’s it!As you can see the code here is so much easier to read than the alternative. With proper documentation (in the CFC and hard copy) one can easily make modifications to the existing code.Future:

I can imagine many improvements to the code shown above (and I’m sure you can too). For example, one can create a function that evaluates the string variable based on a specific passed-in value – not just blank/non-blank.

If you have any suggestions or comments feel free to contact me – We all benefit from the wisdom of many.

Ciao

Advertisements
Comments
  1. Kris Brixon says:

    The concept is fine, this is similar to some programs that use bit manipulation to handle security roles:

    http://www.colderfusion.com/presentations/darthur/Bitwise_Security.ppt

  2. therush says:

    You are absolutely correct. I got the idea from just such a concept. I saw that the Bit function work on numbers and not strings so I decided to be creative. Thanks for the PPT link!

  3. Jeff Price says:

    If I could make one suggestion….ditch the evalStringToNumber function and replace it with a generic function that takes and array as a parameter and will spit out a total number. This way you can add arguments as you see fit without worrying about anything! I hope this formats correctly! Just my $0.02. I would look at your evalStringToNumber and think…this just replaces the string with the number passed? WTF was he doing using a function for that! 😛

  4. Jeff Price says:

    Haha! Can’t post code to a programming website. Zap me an e-mail and I’ll send it to you.

  5. therush says:

    That’s what I love about the internet – a global community in which to share words and ideas (and photos, and video, etc – you get the idea).

    Interesting idea Jeff. I could simply do away with the number parameter and pass into the function an array or structure containing the values. Nice! Thanks!

    rushint AT yahoo DOT com

  6. Jeff Houser says:

    You may want to do some research into K Maps: http://en.wikipedia.org/wiki/Karnaugh_map
    They are used for Boolean simplification.

  7. therush says:

    “Damn it Jeff, I’m a programmer not a mathematician” 🙂 But really, boolean logic was one of my favorite subjects in school. Thanks for the post.

    BTW – It was really nice meeting you at Flex Camp Boston. I’ll be looking forward to the next episode. I was looking to make a deal with the guy who won the Wii but he disapeared from the hall faster than … (fill in the blank).

  8. Idetrorce says:

    very interesting, but I don’t agree with you
    Idetrorce

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s