10 # LOAD FILTERING MODULE...
11 use Filter::Util::Call;
15 # CATCH ATTEMPTS TO CALL case OUTSIDE THE SCOPE OF ANY switch
17 $::_S_W_I_T_C_H = sub { croak "case/when statement not in switch/given block" };
21 my ($Perl5, $Perl6) = (0,0);
25 $fallthrough = grep /\bfallthrough\b/, @_;
26 $offset = (caller)[2]+1;
27 filter_add({}) unless @_>1 && $_[1] eq 'noimport';
30 for ( qw( on_defined on_exists ) )
32 *{"${pkg}::$_"} = \&$_;
34 *{"${pkg}::__"} = \&__ if grep /__/, @_;
35 $Perl6 = 1 if grep(/Perl\s*6/i, @_);
36 $Perl5 = 1 if grep(/Perl\s*5/i, @_) || !grep(/Perl\s*6/i, @_);
48 local $Switch::file = (caller)[1];
51 $status = filter_read(1_000_000);
52 return $status if $status<0;
53 $_ = filter_blocks($_,$offset);
54 $_ = "# line $offset\n" . $_ if $offset; undef $offset;
58 use Text::Balanced ':ALL';
62 my ($pretext,$offset) = @_;
63 ($pretext=~tr/\n/\n/)+($offset||0);
68 local $SIG{__WARN__}=sub{die$@};
70 my $ishash = defined eval 'my $hr='.$_[0];
77 my $CUT = qr/\n=cut.*$EOP/;
78 my $pod_or_DATA = qr/ ^=(?:head[1-4]|item) .*? $CUT
81 | ^=begin \s* (\S+) .*? \n=end \s* \1 .*? $EOP
88 my ($source, $line) = @_;
89 return $source unless $Perl5 && $source =~ /case|switch/
90 || $Perl6 && $source =~ /when|given|default/;
93 component: while (pos $source < length $source)
95 if ($source =~ m/(\G\s*use\s+Switch\b)/gc)
97 $text .= q{use Switch 'noimport'};
100 my @pos = Text::Balanced::_match_quotelike(\$source,qr/\s*/,1,0);
103 my $pre = substr($source,$pos[0],$pos[1]); # matched prefix
105 if( substr($source,$pos[4],$pos[5]) eq '/' && # 1st delimiter
106 substr($source,$pos[2],$pos[3]) eq '' && # no op like 'm'
107 index( substr($source,$pos[16],$pos[17]), 'x' ) == -1 && # no //x
108 ($iEol = index( $source, "\n", $pos[4] )) > 0 &&
109 $iEol < $pos[8] ){ # embedded newlines
110 # If this is a pattern, it isn't compatible with Switch. Backup past 1st '/'.
111 pos( $source ) = $pos[6];
112 $text .= $pre . substr($source,$pos[2],$pos[6]-$pos[2]);
114 $text .= $pre . substr($source,$pos[2],$pos[18]-$pos[2]);
118 if ($source =~ m/\G\s*($pod_or_DATA)/gc) {
121 @pos = Text::Balanced::_match_variable(\$source,qr/\s*/);
124 $text .= " " if $pos[0] < $pos[2];
125 $text .= substr($source,$pos[0],$pos[4]-$pos[0]);
129 if ($Perl5 && $source =~ m/\G(\n*)(\s*)(switch)\b(?=\s*[(])/gc
130 || $Perl6 && $source =~ m/\G(\n*)(\s*)(given)\b(?=\s*[(])/gc
131 || $Perl6 && $source =~ m/\G(\n*)(\s*)(given)\b(.*)(?=\{)/gc)
135 $text .= $1.$2.'S_W_I_T_C_H: while (1) ';
137 @pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\(/,qr/\)/,qr/[[{(<]/,qr/[]})>]/,undef)
139 die "Bad $keyword statement (problem in the parentheses?) near $Switch::file line ", line(substr($source,0,pos $source),$line), "\n";
141 $arg = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
143 $arg =~ s {^\s*[(]\s*%} { ( \\\%} ||
144 $arg =~ s {^\s*[(]\s*m\b} { ( qr} ||
145 $arg =~ s {^\s*[(]\s*/} { ( qr/} ||
146 $arg =~ s {^\s*[(]\s*qw} { ( \\qw};
147 @pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\{/,qr/\}/,qr/\{/,qr/\}/,undef)
149 die "Bad $keyword statement (problem in the code block?) near $Switch::file line ", line(substr($source,0, pos $source), $line), "\n";
151 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
152 $code =~ s/{/{ local \$::_S_W_I_T_C_H; Switch::switch $arg;/;
153 $text .= $code . 'continue {last}';
156 elsif ($Perl5 && $source =~ m/\G(\s*)(case\b)(?!\s*=>)/gc
157 || $Perl6 && $source =~ m/\G(\s*)(when\b)(?!\s*=>)/gc
158 || $Perl6 && $source =~ m/\G(\s*)(default\b)(?=\s*\{)/gc)
161 $text .= $1 . ($keyword eq "default"
163 : "if (Switch::case");
165 if ($keyword eq "default") {
168 elsif (@pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\{/,qr/\}/,qr/\{/,qr/\}/,undef)) {
169 my $code = substr($source,$pos[0],$pos[4]-$pos[0]);
170 $text .= " " if $pos[0] < $pos[2];
171 $text .= "sub " if is_block $code;
172 $text .= filter_blocks($code,line(substr($source,0,$pos[0]),$line)) . ")";
174 elsif (@pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/[[(]/,qr/[])]/,qr/[[({]/,qr/[])}]/,undef)) {
175 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
176 $code =~ s {^\s*[(]\s*%} { ( \\\%} ||
177 $code =~ s {^\s*[(]\s*m\b} { ( qr} ||
178 $code =~ s {^\s*[(]\s*/} { ( qr/} ||
179 $code =~ s {^\s*[(]\s*qw} { ( \\qw};
180 $text .= " " if $pos[0] < $pos[2];
183 elsif ($Perl6 && do{@pos = Text::Balanced::_match_variable(\$source,qr/\s*/)}) {
184 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
185 $code =~ s {^\s*%} { \%} ||
186 $code =~ s {^\s*@} { \@};
187 $text .= " " if $pos[0] < $pos[2];
190 elsif ( @pos = Text::Balanced::_match_quotelike(\$source,qr/\s*/,1,0)) {
191 my $code = substr($source,$pos[2],$pos[18]-$pos[2]);
192 $code = filter_blocks($code,line(substr($source,0,$pos[2]),$line));
193 $code =~ s {^\s*m} { qr} ||
194 $code =~ s {^\s*/} { qr/} ||
195 $code =~ s {^\s*qw} { \\qw};
196 $text .= " " if $pos[0] < $pos[2];
199 elsif ($Perl5 && $source =~ m/\G\s*(([^\$\@{])[^\$\@{]*)(?=\s*{)/gc
200 || $Perl6 && $source =~ m/\G\s*([^;{]*)()/gc) {
201 my $code = filter_blocks($1,line(substr($source,0,pos $source),$line));
202 $text .= ' \\' if $2 eq '%';
206 die "Bad $keyword statement (invalid $keyword value?) near $Switch::file line ", line(substr($source,0,pos $source), $line), "\n";
209 die "Missing opening brace or semi-colon after 'when' value near $Switch::file line ", line(substr($source,0,pos $source), $line), "\n"
210 unless !$Perl6 || $source =~ m/\G(\s*)(?=;|\{)/gc;
212 do{@pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\{/,qr/\}/,qr/\{/,qr/\}/,undef)}
214 if ($source =~ m/\G\s*(?=([};]|\Z))/gc) {
218 die "Bad $keyword statement (problem in the code block?) near $Switch::file line ", line(substr($source,0,pos $source),$line), "\n";
220 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
221 $code =~ s/}(?=\s*\Z)/;last S_W_I_T_C_H }/
223 $text .= "{ while (1) $code continue { goto C_A_S_E_$casecounter } last S_W_I_T_C_H; C_A_S_E_$casecounter: }";
228 $source =~ m/\G(\s*(-[sm]\s+|\w+|#.*\n|\W))/gc;
240 for my $nextx ( @$x )
242 my $numx = ref($nextx) || defined $nextx && (~$nextx&$nextx) eq 0;
243 for my $j ( 0..$#$y )
245 my $nexty = $y->[$j];
246 push @numy, ref($nexty) || defined $nexty && (~$nexty&$nexty) eq 0
248 return 1 if $numx && $numy[$j] && $nextx==$nexty
258 my $ref = @_==1 && ref($_[0]) eq 'HASH' ? $_[0] : { @_ };
264 my $ref = @_==1 && ref($_[0]) eq 'HASH' ? $_[0] : { @_ };
265 [ grep { defined $ref->{$_} } keys %$ref ]
270 my ($s_val) = @_ ? $_[0] : $_;
271 my $s_ref = ref $s_val;
273 if ($s_ref eq 'CODE')
276 sub { my $c_val = $_[0];
277 return $s_val == $c_val if ref $c_val eq 'CODE';
278 return $s_val->(@$c_val) if ref $c_val eq 'ARRAY';
279 return $s_val->($c_val);
282 elsif ($s_ref eq "" && defined $s_val && (~$s_val&$s_val) eq 0) # NUMERIC SCALAR
285 sub { my $c_val = $_[0];
286 my $c_ref = ref $c_val;
287 return $s_val == $c_val if $c_ref eq ""
289 && (~$c_val&$c_val) eq 0;
290 return $s_val eq $c_val if $c_ref eq "";
291 return in([$s_val],$c_val) if $c_ref eq 'ARRAY';
292 return $c_val->($s_val) if $c_ref eq 'CODE';
293 return $c_val->call($s_val) if $c_ref eq 'Switch';
294 return scalar $s_val=~/$c_val/
295 if $c_ref eq 'Regexp';
296 return scalar $c_val->{$s_val}
301 elsif ($s_ref eq "") # STRING SCALAR
304 sub { my $c_val = $_[0];
305 my $c_ref = ref $c_val;
306 return $s_val eq $c_val if $c_ref eq "";
307 return in([$s_val],$c_val) if $c_ref eq 'ARRAY';
308 return $c_val->($s_val) if $c_ref eq 'CODE';
309 return $c_val->call($s_val) if $c_ref eq 'Switch';
310 return scalar $s_val=~/$c_val/
311 if $c_ref eq 'Regexp';
312 return scalar $c_val->{$s_val}
317 elsif ($s_ref eq 'ARRAY')
320 sub { my $c_val = $_[0];
321 my $c_ref = ref $c_val;
322 return in($s_val,[$c_val]) if $c_ref eq "";
323 return in($s_val,$c_val) if $c_ref eq 'ARRAY';
324 return $c_val->(@$s_val) if $c_ref eq 'CODE';
325 return $c_val->call(@$s_val)
326 if $c_ref eq 'Switch';
327 return scalar grep {$_=~/$c_val/} @$s_val
328 if $c_ref eq 'Regexp';
329 return scalar grep {$c_val->{$_}} @$s_val
334 elsif ($s_ref eq 'Regexp')
337 sub { my $c_val = $_[0];
338 my $c_ref = ref $c_val;
339 return $c_val=~/s_val/ if $c_ref eq "";
340 return scalar grep {$_=~/s_val/} @$c_val
341 if $c_ref eq 'ARRAY';
342 return $c_val->($s_val) if $c_ref eq 'CODE';
343 return $c_val->call($s_val) if $c_ref eq 'Switch';
344 return $s_val eq $c_val if $c_ref eq 'Regexp';
345 return grep {$_=~/$s_val/ && $c_val->{$_}} keys %$c_val
350 elsif ($s_ref eq 'HASH')
353 sub { my $c_val = $_[0];
354 my $c_ref = ref $c_val;
355 return $s_val->{$c_val} if $c_ref eq "";
356 return scalar grep {$s_val->{$_}} @$c_val
357 if $c_ref eq 'ARRAY';
358 return $c_val->($s_val) if $c_ref eq 'CODE';
359 return $c_val->call($s_val) if $c_ref eq 'Switch';
360 return grep {$_=~/$c_val/ && $s_val->{"$_"}} keys %$s_val
361 if $c_ref eq 'Regexp';
362 return $s_val==$c_val if $c_ref eq 'HASH';
366 elsif ($s_ref eq 'Switch')
369 sub { my $c_val = $_[0];
370 return $s_val == $c_val if ref $c_val eq 'Switch';
371 return $s_val->call(@$c_val)
372 if ref $c_val eq 'ARRAY';
373 return $s_val->call($c_val);
378 croak "Cannot switch on $s_ref";
383 sub case($) { local $SIG{__WARN__} = \&carp;
384 $::_S_W_I_T_C_H->(@_); }
388 my $placeholder = bless { arity=>1, impl=>sub{$_[1+$_[0]]} };
390 sub __() { $placeholder }
395 bless { arity=>0, impl=>sub{$_[$index]} };
405 my ($self,@args) = @_;
406 return $self->{impl}->(0,@args);
414 my ($left, $right, $reversed) = @_;
415 ($right,$left) = @_ if $reversed;
417 my $rop = ref $right eq 'Switch'
419 : bless { arity=>0, impl=>sub{$right} };
421 my $lop = ref $left eq 'Switch'
423 : bless { arity=>0, impl=>sub{$left} };
425 my $arity = $lop->{arity} + $rop->{arity};
429 impl => sub { my $start = shift;
430 return $op->($lop->{impl}->($start,@_),
431 $rop->{impl}->($start+$lop->{arity},@_));
444 my $lop = ref $left eq 'Switch'
446 : bless { arity=>0, impl=>sub{$left} };
448 my $arity = $lop->{arity};
452 impl => sub { $op->($lop->{impl}->(@_)) }
459 "+" => meta_bop {$_[0] + $_[1]},
460 "-" => meta_bop {$_[0] - $_[1]},
461 "*" => meta_bop {$_[0] * $_[1]},
462 "/" => meta_bop {$_[0] / $_[1]},
463 "%" => meta_bop {$_[0] % $_[1]},
464 "**" => meta_bop {$_[0] ** $_[1]},
465 "<<" => meta_bop {$_[0] << $_[1]},
466 ">>" => meta_bop {$_[0] >> $_[1]},
467 "x" => meta_bop {$_[0] x $_[1]},
468 "." => meta_bop {$_[0] . $_[1]},
469 "<" => meta_bop {$_[0] < $_[1]},
470 "<=" => meta_bop {$_[0] <= $_[1]},
471 ">" => meta_bop {$_[0] > $_[1]},
472 ">=" => meta_bop {$_[0] >= $_[1]},
473 "==" => meta_bop {$_[0] == $_[1]},
474 "!=" => meta_bop {$_[0] != $_[1]},
475 "<=>" => meta_bop {$_[0] <=> $_[1]},
476 "lt" => meta_bop {$_[0] lt $_[1]},
477 "le" => meta_bop {$_[0] le $_[1]},
478 "gt" => meta_bop {$_[0] gt $_[1]},
479 "ge" => meta_bop {$_[0] ge $_[1]},
480 "eq" => meta_bop {$_[0] eq $_[1]},
481 "ne" => meta_bop {$_[0] ne $_[1]},
482 "cmp" => meta_bop {$_[0] cmp $_[1]},
483 "\&" => meta_bop {$_[0] & $_[1]},
484 "^" => meta_bop {$_[0] ^ $_[1]},
485 "|" => meta_bop {$_[0] | $_[1]},
486 "atan2" => meta_bop {atan2 $_[0], $_[1]},
488 "neg" => meta_uop {-$_[0]},
489 "!" => meta_uop {!$_[0]},
490 "~" => meta_uop {~$_[0]},
491 "cos" => meta_uop {cos $_[0]},
492 "sin" => meta_uop {sin $_[0]},
493 "exp" => meta_uop {exp $_[0]},
494 "abs" => meta_uop {abs $_[0]},
495 "log" => meta_uop {log $_[0]},
496 "sqrt" => meta_uop {sqrt $_[0]},
497 "bool" => sub { croak "Can't use && or || in expression containing __" },
499 # "&()" => sub { $_[0]->{impl} },
501 # "||" => meta_bop {$_[0] || $_[1]},
502 # "&&" => meta_bop {$_[0] && $_[1]},
512 Switch - A switch statement for Perl
516 This document describes version 2.11 of Switch,
517 released Nov 22, 2006.
524 case 1 { print "number 1" }
525 case "a" { print "string a" }
526 case [1..10,42] { print "number in list" }
527 case (\@array) { print "number in list" }
528 case /\w+/ { print "pattern" }
529 case qr/\w+/ { print "pattern" }
530 case (\%hash) { print "entry in hash" }
531 case (\&sub) { print "arg to subroutine" }
532 else { print "previous case not true" }
537 [Skip ahead to L<"DESCRIPTION"> if you don't care about the whys
538 and wherefores of this control structure]
540 In seeking to devise a "Swiss Army" case mechanism suitable for Perl,
541 it is useful to generalize this notion of distributed conditional
542 testing as far as possible. Specifically, the concept of "matching"
543 between the switch value and the various case values need not be
544 restricted to numeric (or string or referential) equality, as it is in other
545 languages. Indeed, as Table 1 illustrates, Perl
546 offers at least eighteen different ways in which two values could
549 Table 1: Matching a switch value ($s) with a case value ($c)
551 Switch Case Type of Match Implied Matching Code
553 ====== ===== ===================== =============
555 number same numeric or referential match if $s == $c;
558 object method result of method call match if $s->$c();
559 ref name match if defined $s->$c();
562 other other string equality match if $s eq $c;
566 string regexp pattern match match if $s =~ /$c/;
568 array scalar array entry existence match if 0<=$c && $c<@$s;
569 ref array entry definition match if defined $s->[$c];
570 array entry truth match if $s->[$c];
572 array array array intersection match if intersects(@$s, @$c);
573 ref ref (apply this table to
574 all pairs of elements
578 array regexp array grep match if grep /$c/, @$s;
581 hash scalar hash entry existence match if exists $s->{$c};
582 ref hash entry definition match if defined $s->{$c};
583 hash entry truth match if $s->{$c};
585 hash regexp hash grep match if grep /$c/, keys %$s;
588 sub scalar return value defn match if defined $s->($c);
589 ref return value truth match if $s->($c);
591 sub array return value defn match if defined $s->(@$c);
592 ref ref return value truth match if $s->(@$c);
595 In reality, Table 1 covers 31 alternatives, because only the equality and
596 intersection tests are commutative; in all other cases, the roles of
597 the C<$s> and C<$c> variables could be reversed to produce a
598 different test. For example, instead of testing a single hash for
599 the existence of a series of keys (C<match if exists $s-E<gt>{$c}>),
600 one could test for the existence of a single key in a series of hashes
601 (C<match if exists $c-E<gt>{$s}>).
605 The Switch.pm module implements a generalized case mechanism that covers
606 most (but not all) of the numerous possible combinations of switch and case
607 values described above.
609 The module augments the standard Perl syntax with two new control
610 statements: C<switch> and C<case>. The C<switch> statement takes a
611 single scalar argument of any type, specified in parentheses.
612 C<switch> stores this value as the
613 current switch value in a (localized) control variable.
614 The value is followed by a block which may contain one or more
615 Perl statements (including the C<case> statement described below).
616 The block is unconditionally executed once the switch value has
619 A C<case> statement takes a single scalar argument (in mandatory
620 parentheses if it's a variable; otherwise the parens are optional) and
621 selects the appropriate type of matching between that argument and the
622 current switch value. The type of matching used is determined by the
623 respective types of the switch value and the C<case> argument, as
624 specified in Table 1. If the match is successful, the mandatory
625 block associated with the C<case> statement is executed.
627 In most other respects, the C<case> statement is semantically identical
628 to an C<if> statement. For example, it can be followed by an C<else>
629 clause, and can be used as a postfix statement qualifier.
631 However, when a C<case> block has been executed control is automatically
632 transferred to the statement after the immediately enclosing C<switch>
633 block, rather than to the next statement within the block. In other
634 words, the success of any C<case> statement prevents other cases in the
635 same scope from executing. But see L<"Allowing fall-through"> below.
637 Together these two new statements provide a fully generalized case
644 %special = ( woohoo => 1, d'oh => 1 );
649 case (%special) { print "homer\n"; } # if $special{$_}
650 case /[a-z]/i { print "alpha\n"; } # if $_ =~ /a-z/i
651 case [1..9] { print "small num\n"; } # if $_ in [1..9]
652 case { $_[0] >= 10 } { print "big num\n"; } # if $_ >= 10
653 print "must be punctuation\n" case /\W/; # if $_ ~= /\W/
657 Note that C<switch>es can be nested within C<case> (or any other) blocks,
658 and a series of C<case> statements can try different types of matches
659 -- hash membership, pattern match, array intersection, simple equality,
660 etc. -- against the same switch value.
662 The use of intersection tests against an array reference is particularly
663 useful for aggregating integral cases:
667 switch ($_[0]) { case 0 { return 'zero' }
668 case [2,4,6,8] { return 'even' }
669 case [1,3,5,7,9] { return 'odd' }
670 case /[A-F]/i { return 'hex' }
675 =head2 Allowing fall-through
677 Fall-though (trying another case after one has already succeeded)
678 is usually a Bad Idea in a switch statement. However, this
679 is Perl, not a police state, so there I<is> a way to do it, if you must.
681 If a C<case> block executes an untargeted C<next>, control is
682 immediately transferred to the statement I<after> the C<case> statement
683 (i.e. usually another case), rather than out of the surrounding
689 case 1 { handle_num_1(); next } # and try next case...
690 case "1" { handle_str_1(); next } # and try next case...
691 case [0..9] { handle_num_any(); } # and we're done
692 case /\d/ { handle_dig_any(); next } # and try next case...
693 case /.*/ { handle_str_any(); next } # and try next case...
696 If $val held the number C<1>, the above C<switch> block would call the
697 first three C<handle_...> subroutines, jumping to the next case test
698 each time it encountered a C<next>. After the third C<case> block
699 was executed, control would jump to the end of the enclosing
702 On the other hand, if $val held C<10>, then only the last two C<handle_...>
703 subroutines would be called.
705 Note that this mechanism allows the notion of I<conditional fall-through>.
709 case [0..9] { handle_num_any(); next if $val < 7; }
710 case /\d/ { handle_dig_any(); }
713 If an untargeted C<last> statement is executed in a case block, this
714 immediately transfers control out of the enclosing C<switch> block
715 (in other words, there is an implicit C<last> at the end of each
716 normal C<case> block). Thus the previous example could also have been
720 case [0..9] { handle_num_any(); last if $val >= 7; next; }
721 case /\d/ { handle_dig_any(); }
725 =head2 Automating fall-through
727 In situations where case fall-through should be the norm, rather than an
728 exception, an endless succession of terminal C<next>s is tedious and ugly.
729 Hence, it is possible to reverse the default behaviour by specifying
730 the string "fallthrough" when importing the module. For example, the
731 following code is equivalent to the first example in L<"Allowing fall-through">:
733 use Switch 'fallthrough';
736 case 1 { handle_num_1(); }
737 case "1" { handle_str_1(); }
738 case [0..9] { handle_num_any(); last }
739 case /\d/ { handle_dig_any(); }
740 case /.*/ { handle_str_any(); }
743 Note the explicit use of a C<last> to preserve the non-fall-through
744 behaviour of the third case.
748 =head2 Alternative syntax
750 Perl 6 will provide a built-in switch statement with essentially the
751 same semantics as those offered by Switch.pm, but with a different
752 pair of keywords. In Perl 6 C<switch> will be spelled C<given>, and
753 C<case> will be pronounced C<when>. In addition, the C<when> statement
754 will not require switch or case values to be parenthesized.
756 This future syntax is also (largely) available via the Switch.pm module, by
757 importing it with the argument C<"Perl6">. For example:
762 when 1 { handle_num_1(); }
763 when ($str1) { handle_str_1(); }
764 when [0..9] { handle_num_any(); last }
765 when /\d/ { handle_dig_any(); }
766 when /.*/ { handle_str_any(); }
767 default { handle anything else; }
770 Note that scalars still need to be parenthesized, since they would be
773 Note too that you can mix and match both syntaxes by importing the module
776 use Switch 'Perl5', 'Perl6';
779 =head2 Higher-order Operations
781 One situation in which C<switch> and C<case> do not provide a good
782 substitute for a cascaded C<if>, is where a switch value needs to
783 be tested against a series of conditions. For example:
787 case { $_[0] < 10 } { return 'milk' }
788 case { $_[0] < 20 } { return 'coke' }
789 case { $_[0] < 30 } { return 'beer' }
790 case { $_[0] < 40 } { return 'wine' }
791 case { $_[0] < 50 } { return 'malt' }
792 case { $_[0] < 60 } { return 'Moet' }
793 else { return 'milk' }
797 (This is equivalent to writing C<case (sub { $_[0] < 10 })>, etc.; C<$_[0]>
798 is the argument to the anonymous subroutine.)
800 The need to specify each condition as a subroutine block is tiresome. To
801 overcome this, when importing Switch.pm, a special "placeholder"
802 subroutine named C<__> [sic] may also be imported. This subroutine
803 converts (almost) any expression in which it appears to a reference to a
804 higher-order function. That is, the expression:
814 With C<__>, the previous ugly case statements can be rewritten:
816 case __ < 10 { return 'milk' }
817 case __ < 20 { return 'coke' }
818 case __ < 30 { return 'beer' }
819 case __ < 40 { return 'wine' }
820 case __ < 50 { return 'malt' }
821 case __ < 60 { return 'Moet' }
822 else { return 'milk' }
824 The C<__> subroutine makes extensive use of operator overloading to
825 perform its magic. All operations involving __ are overloaded to
826 produce an anonymous subroutine that implements a lazy version
827 of the original operation.
829 The only problem is that operator overloading does not allow the
830 boolean operators C<&&> and C<||> to be overloaded. So a case statement
833 case 0 <= __ && __ < 10 { return 'digit' }
835 doesn't act as expected, because when it is
836 executed, it constructs two higher order subroutines
837 and then treats the two resulting references as arguments to C<&&>:
839 sub { 0 <= $_[0] } && sub { $_[0] < 10 }
841 This boolean expression is inevitably true, since both references are
842 non-false. Fortunately, the overloaded C<'bool'> operator catches this
843 situation and flags it as an error.
847 The module is implemented using Filter::Util::Call and Text::Balanced
848 and requires both these modules to be installed.
852 Damian Conway (damian@conway.org). This module is now maintained by Rafael
853 Garcia-Suarez (rgarciasuarez@gmail.com) and more generally by the Perl 5
854 Porters (perl5-porters@perl.org), as part of the Perl core.
858 There are undoubtedly serious bugs lurking somewhere in code this funky :-)
859 Bug reports and other feedback are most welcome.
863 Due to the heuristic nature of Switch.pm's source parsing, the presence of
864 regexes with embedded newlines that are specified with raw C</.../>
865 delimiters and don't have a modifier C<//x> are indistinguishable from
866 code chunks beginning with the division operator C</>. As a workaround
867 you must use C<m/.../> or C<m?...?> for such patterns. Also, the presence
868 of regexes specified with raw C<?...?> delimiters may cause mysterious
869 errors. The workaround is to use C<m?...?> instead.
871 Due to the way source filters work in Perl, you can't use Switch inside
874 If your source file is longer then 1 million characters and you have a
875 switch statement that crosses the 1 million (or 2 million, etc.)
876 character boundary you will get mysterious errors. The workaround is to
877 use smaller source files.
881 Copyright (c) 1997-2006, Damian Conway. All Rights Reserved.
882 This module is free software. It may be used, redistributed
883 and/or modified under the same terms as Perl itself.