I know Perl now has given
and when
to simulate switch/case statements, but these are still experimental and are not guaranteed to be in future versions. Also there was a Switch module for Perl that existed in older versions, but it used source filtering and was considered not very good either so it went away.
Because of this, I decided to write my own module to simulate switch/case statements.
package Switch;
# Always use these
use strict;
use warnings;
# Imported modules
use Carp;
# Exporter
use Exporter qw(import);
our @EXPORT = qw(switch case break);
# Variable used to break out of the switch statement
my $BREAK;
sub switch {
my $switch = shift;
my @cases = @_;
# Check that each case has a function associated with it
if (scalar @cases % 2) {
croak "Invalid format in switch statement";
}
# Initialize BREAK
$BREAK = 0;
# Loop through each case
while (my ($case, $code) = splice @cases, 0, 2) {
# Check that $code is a code reference
if (ref $code ne 'CODE') {
$case = ref 'ARRAY' ? join ', ', @{$case} : $case;
croak "case($case) does not have a valid function";
}
# Handle the default case
if ($case eq 'default') { $code->(); next; }
# Handle all other cases
for (@{$case}) {
$code->() if $_ eq $switch;
}
# Exit loop if BREAK is true
last if $BREAK;
}
}
# Construct an array reference of cases
sub case {
return \@_;
}
# BREAK from the switch statement
sub break {
$BREAK = 1;
}
1;
__END__
=head1 NAME
Switch - switch statements for Perl.
=head1 VERSION
$Revision: 1.1 $
=head1 SYNOPSIS
use Switch;
# Define a switch variable
$switch = 3;
# Implement a simple switch statement
switch($switch,
case(1) => sub { print "\$switch = 1\n"; break; },
case(2, 3) => sub { print "\$switch = 2 or 3\n"; },
case(3) => sub { print "\$switch = 3\n"; break; },
default => sub { print "default\n"; },
);
=head1 DESCRIPTION
The Switch module is designed to implement C-style switch statements in Perl. The provided
switch variable will be tested against each case and will execute any/all matching cases until all
cases are tested or a break is encountered.
I have included some simple POD documentation that describes the usage.
To me the syntax looks quite elegant (it was the best I could do without using some sort of source filter myself).
What do you think?
What could be Improved?
$code->() if $_ eq $switch;
Just to clarify, you're testing for hard equality, not the possibility of a regex/range/etc? If so, a hash might be a better choice. \$\endgroup\$ – user1149 Apr 29 '16 at 18:55# Always use these
,# Exporter
, and# Imported modules
are just nuisances that clouds the code. The ideal is for a program to be written so that it needs no comments at all \$\endgroup\$ – Borodin Jun 6 '16 at 0:03