| Search perlmeme.org | |
| Home » Howtos » Syntax » Switch statements |
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;
# Subroutine prototypes
sub do_exit();
sub query_account_status();
sub process_direct_deposits();
# Print the menu selection
print <<"EOT";
Select one of:
1. Process Direct Deposists
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;
}
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 staggering, 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;
# Subroutine prototypes
sub do_exit();
sub query_account_status();
sub process_direct_deposits();
# 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 Deposists
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;
}