Die Flagge des Marasek

Dekostreifen

Deutsch

Current Texts Comic Imprint Calendar Search PHP-Classes Container-Wizard main.s21

Categories

Class Library
Computers
Gaming
Global Politics
Programming
Society
Weblog
World Outlook
{{login}}

What else than ELSEIF?

Permalink
Previous: Paranoid SingletonNext: Multilingual Version
Assigned keywords: Programmieren

Occassionally, in other people's code, I stumble across highly sophisticated, nested IF-statements. Let us, as an example, assume that we're to program the access rules of Herbertstrasse, a famous red light district in Hamburg. Women and children aren't allowed to enter*. Detailed error handling is among the design criteria, telling every individual why it was turned away.

<?php
if($applicant instanceof Woman) {
    
//women are not allowed, regardless of age
    
throw new Exception("women not allowed");
} else {
    
// males are only allowed when they're 18+
    
if($applicant instanceof Man and $applicant->getAge()<18) {
        throw new 
Exception("you are too young to enter");
    }
}
?>

However, on the next morning after the system was introduced, you'll get a friendly visit from several pimps telling you that their girls were turned away by the system because they were correctly identified as women. Of course, you have to allow prostitutes to enter; however, this should be limited to registered prostitutes, not just women passing by:

<?php
if($applicant instanceof Woman) {
    if(
$applicant instanceof Prostitute) {
        if(!
$applicant->hasPermit()) {
            throw new 
Exception("you need a permit to work here");
        } else {
            echo 
"comeon in";
        }
    } else {
        throw new 
Exception("women not allowed");    
    }
    
//women are not allowed, regardless of age
    
} else {
    
// males are only allowed when they're 18+
    
if($applicant instanceof Man and $applicant->getAge()<18) {
        throw new 
Exception("you are too young to enter");
    }
    if(
$applicant instanceof Man and $applicant->getAge()>=18) {
        echo 
"come on in";
    }
throw new 
Exception("you're not allowed to enter");
}
?>

Now this is quite an assortment of brackets and indentations. Of course, that is what the elseif statement is good for:

<?php
if($applicant instanceof Man and $applicant->getAge()>=18) {
    echo 
"comeonin";
} elseif(
$applicant instanceof Man and $applicant->getAge()<18) {
    throw new 
Exception("you are too young to enter");
} elseif(
$applicant instanceof Prostitute and !$applicant->hasPermit()) {
    throw new 
Exception("only registered prostitutes are allowed to enter");
} elseif(
$applicant instanceof Prostitute and $applicant->hasPermit()) {
    echo 
"comeon in";
} elseif(
$applicant instanceof Woman) {
    throw new 
Exception("women not allowed");
} else {
    throw new 
Exception("you're not known");
}
?>

While this is quite the right thing to do, I prefer another way. If I had only one parameter, I would resort to switch...case, which is not possible here, as we have to take into account several factors. However, knowing that switch...case is in the end a special form of endless loop, we can emulate the behaviour of switch...case:

<?php
while(1==1) {
    if(
$applicant instanceof Man and $applicant->getAge()>=18) {
        echo 
"comeon in";
    break;    
    }
    if((
$applicant instanceof Prostitute and $applicant->hasPermit())) {
        echo 
"comeon in";
    break;    
    }
    if(
$applicant instanceof Prostitute) {
        throw new 
Exception("you're not registered");
    break;
    }
    if(
$applicant instanceof Woman) {
        throw new 
Exception("women not allowed");
    break;
    }
    if(
$applicant instanceof Man) {
        throw new 
Exception("you are too young");
    break;
    }
throw new 
Exception("i don't know about you");
break;
}
?>

Here we make an infinite loop which will however be broken in the first run, no matter what (never forget the final break, though). I prefer to use that construct because it puts an emphasis on the modular nature of checks; compare it to a line of guardians who will either sort you out, relegate you to the next one (who does not need to make some checks, as they were made before) or allow you in.

However, doing it the while/elseif-way has a drawback. The internal, forking structure of decisions is not directly reflected in the code anymore.

  • actually, this is not quite true. Herbertstrasse is public ground, so there is no way to truly interdict passage.

Comments

Please note: comments posted won't be visible immediately, as they will be checked for harmful content.

* Title  
* Nickname  
* Comment