-
-
14 Jun 2006 15:30:24 UTC
- Distribution: Switch-Perlish
- Module version: 1.0.5
- Source (raw)
- Browse (raw)
- Changes
- How to Contribute
- Issues (1)
- Testers (266 / 265 / 0)
- Kwalitee
Bus factor: 0- License: unknown
- Activity
24 month- Tools
- Download (17.26KB)
- MetaCPAN Explorer
- Permissions
- Subscribe to distribution
- Permalinks
- This version
- Latest version
- Dependencies
- Scalar::Util
- and possibly others
- Reverse dependencies
- CPAN Testers List
- Dependency graph
NAME
Switch::Perlish - A Perlish implementation of the
switch
statement.VERSION
1.0.5 - Mostly cosmetic changes for this release.
SYNOPSIS
use Switch::Perlish; switch $var, sub { case 'foo', sub { print "$var is equal to 'foo'\n" }; case 42, sub { print "$var is equal to 42\n"; fallthrough }; case [qw/ foo bar baz /], sub { print "$var found in list\n" }; case { foo => 'bar' }, sub { print "$var key found in hash\n" }; case \&func, sub { print "$var as arg to func() returned true\n" }; case $obj, sub { print "$var is method in $obj and returned true\n" }; case qr/\bfoo\b/, sub { print "$var matched against foo\n" }; default sub { print "$var did not find a match\n" }; };
BACKGROUND
If you're unfamiliar with
switch
then this is the best place to start. Aswitch
statement is essentially syntactic sugar for anif
/elsif
/else
chain where the same$variable
is tested in every conditional e.g:my $foo = 'a string'; if($foo eq 'something') { print '$foo matched "something"'; } elsif($foo eq 'a string') { print '$foo matched "a string"'; } else { print '$foo matched nothing'; }
This simply matches
$foo
against a series of strings, then defaulting to the lastelse
block if nothing matched. An equivalentswitch
statement (using this module) would be:use Switch::Perlish; my $foo = 'a string'; switch $foo, sub { case 'something', sub { print '$foo matched "something"' }; case 'a string', sub { print '$foo matched "a string"' }; default sub { print '$foo matched nothing' }; };
So the first argument to
switch
is the thing to be tested (in the code above,$foo
), and the second argument is the block of tests. Eachcase
statement matches its first argument against$foo
, and if the match is successful, the associated block is executed, so running the above code outputs:$foo matched "a string"
. Note the use of semi-colon at the end of theswitch
,case
anddefault
calls - they're just simple subroutine calls.DESCRIPTION
This is a Perl-oriented implementation of the
switch
statement. It uses smart-matching incase
s which can be configured and extended by the user. There is no magical syntax soswitch
/case
/default
expect coderefs, which are most simply provided by anonymous subroutines. By default successfulcase
statements do not fall through[1]. To fall through acase
block call thefallthrough
subroutine explicitly. ForC
styleswitch
behaviour[2] simply call the module with an upper-case C i.euse Switch::Perlish 'C';
[1] To 'fall through' in a
case
block means that theswitch
block isn't exited upon success.[2] upon a
case
succesfully matching all subsequentcase
s succeed; to break out from the currentswitch
completely usestop
.Smart Matching
The idea behind smart matching is that the given values are matched in an intelligent manner, so as to get a meaningful result regardless of the values' types. This allows for flexible code and a certain amount of "just do it" when using smart matching. Below is a basic example using smart matching (which is done implictly in
case
) where a simple value is being matched against an array e.guse Switch::Perlish; my $num = $ARGV[0]; switch $num, sub { case undef, sub { die "Usage: $0 NUM\n" }; case [0 .. 10], sub { print "Your number was between 0 and 10" }; case [11 .. 100], sub { print "Your number was between 11 and 100" }; case [101 .. 1000], sub { print "Your number was between 101 and 1000" }; default sub { print "Your number was less than 0 or greater than 1000" }; };
So here the smart matching is checking for the existence of
$num
in the provided arrays. In the above code ranges happen to be used, but any array would suffice. To see how different value types compare with each other see. Switch::Perlish::Smatch::Comparators, which provides descriptions for all the default comparators.The code behind this smart matching can be found in Switch::Perlish::Smatch which itself delegates to the appropriate comparator subroutine depending on the value types. See Switch::Perlish::Smatch for more details on the smart matching implementation and how it can be extended.
COMPARISON
Because there is an existing module which implements
switch
this section intends to provide clarification of the differences that module, Switch, and this one.Native vs. New
To create a more natural
switch
syntax, Switch uses source filters[3], which facilitate the creation of this natural syntax.Switch::Perlish
however uses the native syntax of perl, so what you code is what you see. The big advantage of source filtering is the ability to create new syntax, but it has several disadvantages - the new syntax can conflict with, and break, existing code, the filtered code can be difficult to debug and because you can't easily see the post-filtered code it can be difficult to integrate into production code. The raison d'être for this module is to have the syntax ofswitch
without the baggage that goes with filtered code.Extensibility
The Switch module deals with the Perl's types superbly, however, that is all, so there is no extensibility as such. This module was designed from the outset to allow an extensibilty of how types are dealt with, i.e how they are compared, and this is done through the companion module Switch::Perlish::Smatch.
The
sub
keywordUnlike Switch,
Switch::Perlish
requires the use of the thesub
keyword when creating blocks. This is because there is no standard way of magically coercing bare blocks into closures, unless one uses the(&)
prototype, and that is only applicable where it is the first argument. Also, prototypes are too restrictive for what is intended as a very perlish module e.g$ perl -e 'sub f(&) { print $_[0]->() } sub g{'foo'} my $r = \&g; f $r' Type of arg 1 to main::f must be block or sub {} (not private variable) at -e line 1, at EOF Execution of -e aborted due to compilation errors.
So, for now, 3 extra keystrokes are necessary when using blocks with
Switch::Perlish
.[3] see. Filter::Simple for more info on source filters.
SUBROUTINES
switch( $topic, $block )
-
Execute the given
$block
allowingcase
statements to access the$topic
. This, along withcase
anddefault
, will also attempt to return in the same manner as normal subroutines e.g you can assign to the result of them. case( $match, $block )
-
If the current
$topic
successfully smart matches against$match
then execute$block
and exit from currentswitch
, but if usingC
styleswitch
behaviour, then continue executing the block and all subsequentcase
$block
s until the end of the currentswitch
or a call tostop
. Also, if usingC
styleswitch
behaviour then$block
is optional. NB: this subroutine cannot be called outside ofswitch
, if you want to use smart matching functionality, see. Switch::Perlish::Smatch. default( $block )
-
Execute
$block
and exit fromswitch
. NB: this subroutine cannot be called outside ofswitch
. fallthrough()
-
Fall through the the current
case
block i.e continue to evaluate the rest of theswitch
block. NB: this subroutine cannot be called outside ofcase
. stop()
-
Use in
case
blocks to exit the currentswitch
block, ideally when used with theC
style behaviour as it mimicsC
'sbreak
. NB: this subroutine cannot be called outside ofcase
.
Globals
$SWITCH
-
The current
switch
block. $CASE
-
The current
case
block. $TOPIC
-
The current topic block, also aliased to
$_
. $MATCH
-
The current thing being matched against.
$CSTYLE
-
If
Switch::Perlish
is called with the C argument, this is set to true andC
styleswitch
behaviour is enabled. $FALLING
-
Set to true when falling through the current
switch
block i.e set to true whenfallthrough
has been called.
SEE. ALSO
How do I create a switch or case statement?
Basic_BLOCKs_and_Switch_Statements
Switch::Perlish::Smatch::Comparators
TODO
Implement localizing comparators
Test with earlier versions of
perl
Drop
warnings
for compatibility with older perls?Allow lists as the topic and/or cases to match against
AUTHOR
Dan Brook
<mr.daniel.brook@gmail.com>
COPYRIGHT
Copyright (c) 2006, Dan Brook. All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.
Module Install Instructions
To install Switch::Perlish, copy and paste the appropriate command in to your terminal.
cpanm Switch::Perlish
perl -MCPAN -e shell install Switch::Perlish
For more information on module installation, please visit the detailed CPAN module installation guide.