H:\>perldoc -q switch > switch.txt
H:\>cat switch.txt
Found in d:\Perl\activeperl522\lib\pod\perlfaq7.pod
How do I create a switch or case statement?
This is explained in more depth in the the perlsyn
manpage. Briefly, there's no official case statement,
because of the variety of tests possible in Perl
(numeric comparison, string comparison, glob comparison,
regexp matching, overloaded comparisons, ...). Larry
couldn't decide how best to do this, so he left it out,
even though it's been on the wish list since perl1.
The general answer is to write a construct like this:
for ($variable_to_test) {
if (/pat1/) { } # do something
elsif (/pat2/) { } # do something else
elsif (/pat3/) { } # do something else
else { } # default
}
Here's a simple example of a switch based on pattern
matching, this time lined up in a way to make it look
more like a switch statement. We'll do a multi-way
conditional based on the type of reference stored in
$whatchamacallit:
SWITCH: for (ref $whatchamacallit) {
/^$/ && die "not a reference";
/SCALAR/ && do {
print_scalar($$ref);
last SWITCH;
};
/ARRAY/ && do {
print_array(@$ref);
last SWITCH;
};
/HASH/ && do {
print_hash(%$ref);
last SWITCH;
};
/CODE/ && do {
warn "can't print function
+ ref";
last SWITCH;
};
# DEFAULT
warn "User defined type skipped";
}
See `perlsyn/"Basic BLOCKs and Switch Statements"' for
many other examples in this style.
Sometimes you should change the positions of the
constant and the variable. For example, let's say you
wanted to test which of many answers you were given, but
in a case-insensitive way that also allows
abbreviations. You can use the following technique if
the strings all start with different characters, or if
you want to arrange the matches so that one takes
precedence over another, as `"SEND"' has precedence over
`"STOP"' here:
chomp($answer = <>);
if ("SEND" =~ /^\Q$answer/i) { print "Action is se
+nd\n" }
elsif ("STOP" =~ /^\Q$answer/i) { print "Action is st
+op\n" }
elsif ("ABORT" =~ /^\Q$answer/i) { print "Action is ab
+ort\n" }
elsif ("LIST" =~ /^\Q$answer/i) { print "Action is li
+st\n" }
elsif ("EDIT" =~ /^\Q$answer/i) { print "Action is ed
+it\n" }
A totally different approach is to create a hash of
function references.
my %commands = (
"happy" => \&joy,
"sad", => \&sullen,
"done" => sub { die "See ya!" },
"mad" => \&angry,
);
print "How are you? ";
chomp($string = <STDIN>);
if ($commands{$string}) {
$commands{$string}->();
} else {
print "No such command: $string\n";
}
Christian Lemburg
Brainbench MVP for Perl
http://www.brainbench.com