-
-
16 Apr 2017 20:53:43 UTC
- Distribution: Switch-Plain
- Module version: 0.0501
- Source (raw)
- Browse (raw)
- Changes
- How to Contribute
- Repository
- Issues (0)
- Testers (876 / 0 / 80)
- Kwalitee
Bus factor: 0- 75.61% Coverage
- License: perl_5
- Perl: v5.14.0
- Activity
24 month- Tools
- Download (12.64KB)
- MetaCPAN Explorer
- Permissions
- Subscribe to distribution
- Permalinks
- This version
- Latest version
NAME
Switch::Plain - a simple switch statement for Perl
SYNOPSIS
use Switch::Plain; # string version sswitch (get_me_a_string()) { # return value of get_me_a_string() is bound to $_ in this block case 'foo': { # runs if $_ equals 'foo' } case 'bar': { # runs if $_ equals 'bar' } case 'melonlord' if $DEBUG: { # runs if $_ equals 'melonlord' and $DEBUG is true } default if $VERBOSE > 1: { # runs if nothing else matched so far and $VERBOSE is greater than 1 } default: { # runs if nothing else matched so far } } # number version nswitch (get_me_a_number()) { # return value of get_me_a_number() is bound to $_ in this block case 1: { # runs if $_ equals 1 } case 2: { # runs if $_ equals 2 } case 99 if $DEBUG: { # runs if $_ equals 99 and $DEBUG is true } default if $VERBOSE > 1: { # runs if nothing else matched so far and $VERBOSE is greater than 1 } default: { # runs if nothing else matched so far } }
DESCRIPTION
This module provides (yet another) switch statement for Perl. Differences between this module and Switch include:
It's not a source filter. (It uses perl's pluggable keywords instead.)
It generates non-horrible code. If you want to see this for yourself, run some sample code through
perl -MO=Deparse
.It doesn't try to be smart about matching fancy data structures; it only does simple string or numeric equality tests. This also sets it apart from perl's built in
given
statement and smartmatch operator~~
.
Syntax
This module understands the following grammar:
switch_statement := switch_keyword switch_scrutinee switch_body switch_keyword := 'sswitch' | 'nswitch' switch_scrutinee := '(' EXPR ')' switch_body := '{' case_clause* '}' case_clause := case_pattern+ BLOCK case_pattern := case_keyword case_modifier? ':' case_keyword := 'default' | 'case' EXPR case_modifier := 'if' EXPR | 'unless' EXPR
*
,+
, and?
have their usual regex meaning;BLOCK
andEXPR
represent standard Perl blocks and expressions, respectively.Semantics
The meaning of a switch statement is given by the following translation rules:
sswitch (FOO) { ... }
andnswitch (FOO) { ... }
turn intodo { local *_ = \FOO; ... };
That is, they alias
$_
toFOO
within the body of the switch statement.A series of case clauses in the switch body turns into a single
if
/elsif
chain. That is, the first clause becomes anif
; every subsequent clause becomes anelsif
.case FOO:
becomesif ($_ eq FOO)
forsswitch
andif ($_ == FOO)
fornswitch
.default:
becomesif (1)
.case FOO if BAR:
becomesif ($_ eq FOO && BAR)
forsswitch
andif ($_ == FOO && BAR)
fornswitch
.default if BAR:
becomesif (BAR)
.... unless BAR
works similarly, but with the condition inverted (!BAR
).If there are multiple
case
/default
s before a single block, their conditions are combined with||
.
Here's an example demonstrating all combinations:
sswitch (SCRUTINEE) { case FOO0: { BODY0 } case FOO1: case FOO2 if BAR1: case FOO3 unless BAR2: default if BAR3: default unless BAR4: { BODY1 } default: { BODY2 } }
This is equivalent to:
do { # temporarily alias $_ to SCRUTINEE within this block: local *_ = \SCRUTINEE; if ($_ eq FOO0) { BODY0 } elsif ( $_ eq FOO1 || ($_ eq FOO2 && BAR1) || ($_ eq FOO3 && !BAR2) || BAR3 || !BAR4 ) { BODY1 } elsif (1) { BODY2 } };
Differences between
Switch::Plain
and C'sswitch
C's
switch
is limited to integer scrutinees.Switch::Plain
supports any number or string.C's
case
labels must be compile-time constants.Switch::Plain
allows any expression and even additional arbitrary conditions via theif
/unless
case modifiers.C's
case
labels are actual labels in that they can appear anywhere within theswitch
statement's body (even nested). WithSwitch::Plain
allcase
s must be at the top level.In C the order of the
case
s does not matter since they're all known at compile time and guaranteed to be distinct.Switch::Plain
evaluates them in the order they're written: If you putdefault: { ... }
in the middle of aswitch
, it will intercept all values, and any followingcase
s will be ignored (this is like writing... elsif (1) { ... } else { ... }
).Since C's
case
labels are actual labels and C'sswitch
is effectively a dynamicgoto
, C actually has no concept of a "case clause" or a "case block".switch
simply transfers control to one of thecase
s and that's it. This has the side effect of "fallthrough" behavior if you want to use C'sswitch
to check for multiple distinct cases; that is, you must insert an explicitbreak;
to leave theswitch
statement when you're done with your case.Switch::Plain
has nothing of the kind. Because it turns into a singleif
/elsif
chain and every case block is clearly delimited, execution ofsswitch
/nswitch
stops as soon one case pattern matches. However, it is possible to attach multiple case patterns to a single block:case 2: case 3: case 5: { ... }
This trivial case works the same way as fallthrough would in C (any value of 2, 3, or 5 is accepted).
Since C's
break
refers to the innermost enclosingswitch
or loop, you can't use it inswitch
to leave a surrounding loop (you have to usegoto
instead). This particular problem would be avoidable in Perl thanks to loop labels; however, this isn't even necessary becausesswitch
/nswitch
work likeif
: They don't count as loops andlast
/next
/redo
ignore them.
Scoping
This module is a lexical pragma, i.e. the effects of
use Switch::Plain
(turningsswitch
andnswitch
into keywords) are scoped to the innermost enclosing block (or the whole file if there is no enclosing block).If you are a module author who wants to wrap
Switch::Plain
from another module, simply callSwitch::Plain->import
from your ownimport
method. It will affect whatever scope is currently being compiled (i.e. your caller).AUTHOR
Lukas Mai,
<l.mai at web.de>
COPYRIGHT & LICENSE
Copyright 2012-2013 Lukas Mai.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
Module Install Instructions
To install Switch::Plain, copy and paste the appropriate command in to your terminal.
cpanm Switch::Plain
perl -MCPAN -e shell install Switch::Plain
For more information on module installation, please visit the detailed CPAN module installation guide.