CASE <expression> OF <value set 1> : <statement 1>; <value set 2> : <statement 2>; <value set n> : <statement n>; [ELSE <statement n+1>] END;
switch( <expression> ) { case <value set 1> : <statement 1>; break; case <value set 2> : <statement 2>; break; case <value set n> : <statement n>; break; [default: <statement n+1>;] }
switch( <expression> ) { case <value set 1> : <statement 1>; break; //The code will hit the break and leave this structure case <value set 2> : <statement 2>; //Notice I didn't say break! Value set 2 will flow on to value set 3! case <value set 3> : <statement 3>; break; }
Answers
Sure, try:
Using the "CASE TRUE of" and "IN []" you can generally achieve what ever you want.
By the way, you can evaluate multiple values in a CASE statement like this:
RIS Plus, LLC
I suppose the repeating of <statment 3> is objectionable.
David's suggestion can easily be turned into which does exactly the same as the CASE statement. (Note that I used the IF within the ELSE as though we had an IF THEN ELIF ELSE structure when it comes to indenting (and pacing BEGIN...END)). With a structured sequence of IF statements, you have more liberty, though, to approximate whatever you want
To evaluate multiple values (meaning more than 2) for one control variable, a CASE statement is more efficient than a construction of nested IF statements, not to mention easier to read.
RIS Plus, LLC
I think you may have misread, and vaprog lists what I believe makes sense: A CASE statement is essentially an IF - ELSE IF - ELSE IF(n). In both situations, CAL is going to find the first argument that evaluates true within the soonest sequential leg, execute it, and leave as soon as possible, WITHOUT touching any other leg.
If we look at David's code and pass in a value of 3, then the last leg will never be evaluated.
Therefore, if I ever want to mirror the functionality of my C++ snippet, I would want to use nested if/else statements. I could technically use the below code, but you can quickly see how nasty it becomes!
Therefore, I'm thinking vaprog's last code snippet is the implementation that we have to live with!
Systems Analyst
NAV 2009 R2 (6.00.34463)
What makes no sense to me is that you would have two different blocks of code for the same value of the control variable, so I always assumed that having two blocks for value '3' was a typo.
My solution would be to have a block for values '2,3' in a CASE statement, and then have an IF statement inside there to catch value 2, which in that case seems to be the exception. More than one way to skin a cat, whatever works for you
RIS Plus, LLC
RIS Plus, LLC
I'd be vary careful in comparing what the debugger does to what the compiler actually creates. I admit, I don't know the answer, but I haven't been very pleased in the past with how the debugger sometimes bounces around, especially after being used to Visual Studio.
That said, I see where you were going.
Hmm, not bad :-k I really like that.
However, when it came down to the actual implementation, I chose option X! Here's what I've been working on. I chose this way because
-setting the Customer Group is better represented in a separate 'thought'.
The IF statement's evaluation speed is minimal. therefore, I'm not taking a critical hit every time I evaluate.
Thanks everyone for the discussions, I haven't broken down code to the basic building blocks like this for quite some time. It's very nice to step back, think it over, and 'tighten the mental belt!'
Systems Analyst
NAV 2009 R2 (6.00.34463)
Here is some code proving they are actually evaluated. You'll get four messages, three from the CheckCondition function and one from the OnRun trigger.
OnRun()
CASE TRUE OF
CheckCondition(1, 3): MESSAGE('the value is one');
CheckCondition(2, 3): MESSAGE('the value is two');
CheckCondition(3, 3): MESSAGE('the value is three');
ELSE
MESSAGE('the value is four or more');
END;
CheckCondition(MyInt : Integer;Number : Integer) Result : Boolean
Result := (MyInt = Number);
MESSAGE('Condition: ' + FORMAT(Result));
The point was that a CASE statement is evaluated differently than a nested IF construction. My contention is that when evaluating multiple values for a single control variable, a CASE statement is more efficient and easier to read.
RIS Plus, LLC
Agree.
I was going to say I totally disagree, but as it turns out:
"While semantically these two code segments may be the same, their implementation is usually different. Whereas the IF..THEN..ELSEIF chain does a comparison for each conditional statement in the sequence, the SWITCH statement normally uses an indirect jump to transfer control to any one of several statements with a single computation."
It's always a good day when you learn something new.
Wait a second on that... so how does it pick? Does it choose sequentially like I always thought, or pick based on quickest solution, or...? Can you then VERIFY that it will ALWAYS choose that jump?
I present the code below, which will print 'three or two'... basic, but you can see where I'm going with this. Can I ALWAYS rely on NAV to pick the first in the sequence that matches?
Systems Analyst
NAV 2009 R2 (6.00.34463)
If you need it to do something extra for the value 2, you catch it in the '2,3' block like this:
RIS Plus, LLC
Of course you wouldn't ever want to code that way, but saying it is irrelevant isn't a choice - you may one day have to clean it for someone else who is dead and gone (hello government coding job? ).
Unpredictable code branches seem like a recipe for spaghetti at lower levels, and there was a lazy person working on the parser logic . Either we haven't found the answer or it's undocumented.
I know I'm being anal, but now I'm just really interested.
Anyways, mattrax said:
Though I find the following passage in the Microsoft Navision Development I - C/SIDE Introduction (8359B) Chapter 14, page 272 :-s
EDIT: Note that I won't be surprised if the MS documentation is wrong. It hasn't been the first time!
Systems Analyst
NAV 2009 R2 (6.00.34463)
Anyway, why does this matter again?
RIS Plus, LLC
The average time for CASE statements for the nth case:
1) 139.53
5) 498.73
10) 723.09
The average time for IF statements for the nth if:
1) 207.77
5) 915.67
10) 1745.51
So whatever is going on behind the scenes, CASE statements are faster. Regardless, correct programming will solve any issues you might have. That's going to be it for me on this as well.
RIS Plus, LLC
RIS Plus, LLC
You said it in your earlier post. The benefit of CASE is readability, making code that is readable reduces the TCO of the system. It may take a few minutes more to write the code, and it may use more text, but in the long run it is worth it.
Surely not a reason to "give up"?
RIS Plus, LLC
RIS Plus, LLC
I was just disturbed when we were getting beyond the base question (and far off topic) and it sounded like we weren't sure what the compiler was doing, so when everyone starts saying, "stop asking questions, just believe", I can't let go :-# .
The party's over, the lights have been turned off, but I still have to dance out the last song. :oops: I've since done some separate research and discovered that denster/mattrax's initial post are probably both right:
Compilers handle SWITCH/CASE statements differently, and without actually seeing the result, we can't be sure. However, the standard methodology is thus: If the case values are basic and within a narrow range, the compiler will generate a branch table where it can directly access an indexed branch. If the case values are complex or the resulting branch table would result in a large index/large memory footprint, the compiler will generate a result closer to a sequential IF/ELSEIF.
And yes, this is my last post on this topic. :-# :-# :-#
Systems Analyst
NAV 2009 R2 (6.00.34463)