6

To avoid nested if-statements and to improve readability, I wanted to create a switch(true){ ... } statement in Coldfusion. I used this often in php, but when I try this in Coldfusion, I get the following error at initialization:

Template error

This expression must have a constant value.

This happens when a switch case uses a variable in its condition, like:

//this example throws the error
switch(true){
    case foo == 1:
        writeOutput('foo is 1');
    break;
}

Using a switch(true){ ... } statement with constant values (as the error explains) does work:

//this example doesn't throw the error
switch(true){
    case 1 == 1:
        writeOutput('1 is 1');
    break;
}

Is there any way to get the first statement to work in Coldfusion? Maybe with an evaluation of the variable or some trick, or is this a definite no go in Coldfusion?

jan
  • 2,879
  • 2
  • 19
  • 28
  • Nope. Unless they have changed the behavior in CF11, it must be a constant or [written in such a way that it conforms to the constant rule](http://stackoverflow.com/questions/31910902/coldfusion-cfscript-switch-case-where-case-between-a-range). – Leigh Nov 20 '15 at 11:02

3 Answers3

2

In short: no. The case value needs to be something that can be compiled to a constant value. 1==1 can be, as it's just true. foo == 1 cannot be, as foo is only available at runtime.

basically what you're describing is an if / else if / else construct anyhow, so just use one of those.

Adam Cameron
  • 29,677
  • 4
  • 37
  • 78
  • writing it with if / else if / else makes it a bit messy, because it involves a ton of business rules based on certain min and max values, but i guess this is the only way then – jan Nov 23 '15 at 08:08
  • It might be worth looking at if there's a different way to approach the problem full-stop. If you have 500+ cases (as per your comment on Miguel's answer), then the code is a bit smelly anyhow. This is quite possibly something you're aware of already,and are not in the position to deal with now, I realise that. This is just an observation, and not meant to be snippy. – Adam Cameron Nov 23 '15 at 12:10
  • I would need 500+ cases if I use that solution of the second answer, where that value of 'case' is a single constant value. I don't actually have 500+ individual cases :-) – jan Nov 23 '15 at 13:17
2

As Adam and Leigh pointed out, the case values need to be some constant. I'm not sure what your actual use case is but you can do something like this:

switch(foo){
    case 1:
        writeOutput('foo is 1');
    break;
    case 2:
        writeOutput('foo is 2');
    break;
    case 3:
        writeOutput('foo is 3');
    break;
    case 4:
    case 5:
    case 6:
        writeOutput('foo is 4 or 5 or 6');
    break;
    default: 
        writeOutput("I do not have a case to handle this value: #foo#");
}
Miguel-F
  • 13,450
  • 6
  • 38
  • 63
0

As an update on this question, I will note that CF2020 (currently in public beta) has added support for dynamic case values.

And yes, it's done with the understanding that some languages don't allow this, for performance reasons. They are opting to allow it, as other languages do, for readability/flexibility reasons, and leaving the developer to take responsibility for making the cost/benefit tradeoff analysis for their use cases.

charlie arehart
  • 6,590
  • 3
  • 27
  • 25