Tweet

Older versions of Perl have no switch statement. How do I avoid a long if-else-if pattern?

The problem:

You're stuck on a machine that has an old version of Perl on it, (and for whatever reason upgrading Perl is not an option), but you want to implement a switch statement, ie: you have some conditional behaviour that depends on the value of a variable, for example, a user's selection of a menu.

    #!/usr/bin/perl
    use strict;
    use warnings;

    # Print the menu selection
    print <<"EOT";
    Select one of:
    1. Process Direct Deposits
    2. Query account status
    3. Exit
    EOT

    # Get the user's input
    my $menu_item = <>;

    # Take action based on the user's choice
    if ($menu_item == 1) {
        process_direct_deposits();
    } elsif ($menu_item == 2) {
        query_account_status();
    } elsif ($menu_item == 3) {
        do_exit();
    } else {    
        print "I didn't understand the command.\n";
        do_exit();
    }

    exit 0;

    #-------------------------------------------------------------
    # Subroutines
    sub process_direct_deposits {
        print "Processing direct deposits\n";
        return;
    }

    sub query_account_status {
        print "Querying account status\n";
        return;
    }

    sub do_exit {
        print "Exiting...\n";
        return;
    }

Solution: Hashes!

A neat way to avoid the problem is to use a hash.

Use subroutine references in a hash to define what to do for each case:

    my $action_to_take = (    
        1 => \&process_direct_deposits,
        2 => \&query_account_status,
        3 => \&do_exit,
    );

Then where your if statements would be, simply call the subroutine:

    if (defined $action_to_take{$menu_item}) {
        $action_to_take{$menu_item}->();
    } else {
        print "I didn't understand the command.\n";
        do_exit();
    }

While for this small example, the amount of code saved is not large, to include extra cases you only need to add entries to the 'action_to_take' hash, rather than create a whole new section to the if statement.

It also means that you can build the hash in another subroutine and call it somewhere else.

The full example follows:

    #!/usr/bin/perl
    use strict;
    use warnings;

    # Define the actions to take
    my %action_to_take = (
        '1' => \&process_direct_deposits,
        '2' => \&query_account_status,
        '3' => \&do_exit,
    );

    # Print the menu selection
    print <<"EOT";
    Select one of:
    1. Process Direct Deposits
    2. Query account status
    3. Exit
    EOT

    # Get the user's input
    my $menu_item = <>;
    chomp($menu_item);

    # Take action based on the user's choice
    if (defined $action_to_take{$menu_item}) {
        $action_to_take{$menu_item}->();
    } else {
        print "I didn't understand the command.\n";
        do_exit();
    }

    exit 0;

    #-------------------------------------------------------------
    sub process_direct_deposits {
        print "Processing direct deposits\n";
        return;
    }

    sub query_account_status {
        print "Querying account status\n";
        return;
    }

    sub do_exit {
        print "Exiting...\n";
        return;
    }

See also

Or from your command line:
  perldoc Switch
Revision: 1.5 [Top]