5
\$\begingroup\$

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?

toolic
14.6k5 gold badges29 silver badges203 bronze badges
asked Apr 29, 2016 at 14:06
\$\endgroup\$
0

1 Answer 1

3
\$\begingroup\$

so it went away

While it is true that the Switch module was removed from the Core Perl distribution, it is still available on CPAN. Consider changing the name of your module to be unique.

What do you think?

I think it looks good. Here are some suggestions.

Namespace

It is best to import only what is needed to avoid namespace pollution. Change:

use Carp;

to:

use Carp qw(croak);

Documentation

It is great that you added POD, especially with a SYNOPSIS section.

In the SYNOPSIS, it would be better to declare the variable with my so that it runs with strict enabled:

my $switch = 3;

Also in the SYNOPSIS, instead of importing by default:

use Switch;

I recommend you explicitly list all the imported functions:

use Switch qw(switch case break);

This makes the code self-documenting. It makes it more obvious that these are functions from the module as opposed to built-in functions.

Comments

There are several useful comments in the code. However, I agree with user @Borodin who left a comment on the question that the following comments should be deleted:

# Always use these
# Imported modules
# Exporter
answered Dec 15, 2024 at 11:56
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.