Handling more than two possible return values?
When a function returns a boolean, you can easily
if (task()){
// it worked!
}else{
// it failed.
}
But when it returns several different values โโit gets messy
var status = task();
if (status == 1){
// hmm
}else if (status == 2){
// hmmmmm
}else if (status == 3){
// hmmmmmmmm!
}
.. Is there an easier way to handle it?
Edit: In response to the answers recommending switch statements, yes, I am aware of this. I asked for something neater than even that?
source to share
Depends on language capabilities, but I would do something like this in JavaScript:
var handle_task_1 = function () {
// handle task 1
};
var handle_task_2 = function () {
// handle task 2
};
var tasks = {
1: handle_task_1,
2: handle_task_2,
"default": function() {},
};
tasks[task()]();
// Or, with a default action. But it may be too much for some people :)
(tasks[task()] || tasks["default"])();
source to share
Most languages โโhave a switch statement, for example:
switch (task()) {
case 1: // do stuff
break;
case 2: // other stuff
break;
/// etc.
default: // what?!
Error("Unhandleable status code");
}
source to share
If you have multiple chained if statements, each executing a unique block of code, you can use a simple functor class map. Ideally, launching the application will populate this card and you can simply call actions from an instance of that card
The code will look like this:
Action action = (Action) contextMap.get(task());
action.do();
This has the advantage that adding new tasks only requires defining a new class for that task and adding it to the context map at startup.
There are other nice things about this approach too
- taskA () and taskB () can share the same context map and even some of the same actions, so you have less code duplication.
- Actions can be tested more easily (usually)
- Sharing code between activities will be easy without ending up with spaghetti code or complex if (status> 2 && status! = 7) statements
And of course, interfaces, varargs and other syntactic sugars help here.
source to share
If you are talking about an integer or some other primitive return type, the best approach I know is a switch statement.
switch (status)
{
case 1:
// hmm
break;
case 2:
// hmmm
break;
}
However, if you return an object that defines the behavior by following the invocation method, things get a lot neat.
Let's say you have an ISomething interface and two (or more) objects that implement that interface (ASomething and BSomething). If the return type of the method is ISomething, the code will look like this:
ISomething result = task();
result.DoSomething();
source to share
Are you looking for exceptions ?
Then you don't need to clutter your code for the success case, and for different error cases you can use different exceptions as needed.
source to share