MSYS: Update sed to a version that can handle filter-branch examples
[msysgit.git] / lib / perl5 / 5.8.8 / Switch.pm
blob1c130c3d5e7f89d53d8ee29c7956df0a2465d3e6
1 package Switch;
3 use strict;
4 use vars qw($VERSION);
5 use Carp;
7 $VERSION = '2.10_01';
10 # LOAD FILTERING MODULE...
11 use Filter::Util::Call;
13 sub __();
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" };
19 my $offset;
20 my $fallthrough;
21 my ($Perl5, $Perl6) = (0,0);
23 sub import
25 $fallthrough = grep /\bfallthrough\b/, @_;
26 $offset = (caller)[2]+1;
27 filter_add({}) unless @_>1 && $_[1] eq 'noimport';
28 my $pkg = caller;
29 no strict 'refs';
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, @_);
40 sub unimport
42 filter_del()
45 sub filter
47 my($self) = @_ ;
48 local $Switch::file = (caller)[1];
50 my $status = 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;
55 return $status;
58 use Text::Balanced ':ALL';
60 sub line
62 my ($pretext,$offset) = @_;
63 ($pretext=~tr/\n/\n/)+($offset||0);
66 sub is_block
68 local $SIG{__WARN__}=sub{die$@};
69 local $^W=1;
70 my $ishash = defined eval 'my $hr='.$_[0];
71 undef $@;
72 return !$ishash;
76 my $EOP = qr/\n\n|\Z/;
77 my $CUT = qr/\n=cut.*$EOP/;
78 my $pod_or_DATA = qr/ ^=(?:head[1-4]|item) .*? $CUT
79 | ^=pod .*? $CUT
80 | ^=for .*? $EOP
81 | ^=begin \s* (\S+) .*? \n=end \s* \1 .*? $EOP
82 | ^__(DATA|END)__\n.*
83 /smx;
85 my $casecounter = 1;
86 sub filter_blocks
88 my ($source, $line) = @_;
89 return $source unless $Perl5 && $source =~ /case|switch/
90 || $Perl6 && $source =~ /when|given|default/;
91 pos $source = 0;
92 my $text = "";
93 component: while (pos $source < length $source)
95 if ($source =~ m/(\G\s*use\s+Switch\b)/gc)
97 $text .= q{use Switch 'noimport'};
98 next component;
100 my @pos = Text::Balanced::_match_quotelike(\$source,qr/\s*/,1,0);
101 if (defined $pos[0])
103 my $pre = substr($source,$pos[0],$pos[1]); # matched prefix
104 $text .= $pre . substr($source,$pos[2],$pos[18]-$pos[2]);
105 next component;
107 if ($source =~ m/\G\s*($pod_or_DATA)/gc) {
108 next component;
110 @pos = Text::Balanced::_match_variable(\$source,qr/\s*/);
111 if (defined $pos[0])
113 $text .= " " if $pos[0] < $pos[2];
114 $text .= substr($source,$pos[0],$pos[4]-$pos[0]);
115 next component;
118 if ($Perl5 && $source =~ m/\G(\n*)(\s*)(switch)\b(?=\s*[(])/gc
119 || $Perl6 && $source =~ m/\G(\n*)(\s*)(given)\b(?=\s*[(])/gc
120 || $Perl6 && $source =~ m/\G(\n*)(\s*)(given)\b(.*)(?=\{)/gc)
122 my $keyword = $3;
123 my $arg = $4;
124 $text .= $1.$2.'S_W_I_T_C_H: while (1) ';
125 unless ($arg) {
126 @pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\(/,qr/\)/,qr/[[{(<]/,qr/[]})>]/,undef)
127 or do {
128 die "Bad $keyword statement (problem in the parentheses?) near $Switch::file line ", line(substr($source,0,pos $source),$line), "\n";
130 $arg = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
132 $arg =~ s {^\s*[(]\s*%} { ( \\\%} ||
133 $arg =~ s {^\s*[(]\s*m\b} { ( qr} ||
134 $arg =~ s {^\s*[(]\s*/} { ( qr/} ||
135 $arg =~ s {^\s*[(]\s*qw} { ( \\qw};
136 @pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\{/,qr/\}/,qr/\{/,qr/\}/,undef)
137 or do {
138 die "Bad $keyword statement (problem in the code block?) near $Switch::file line ", line(substr($source,0, pos $source), $line), "\n";
140 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
141 $code =~ s/{/{ local \$::_S_W_I_T_C_H; Switch::switch $arg;/;
142 $text .= $code . 'continue {last}';
143 next component;
145 elsif ($Perl5 && $source =~ m/\G(\s*)(case\b)(?!\s*=>)/gc
146 || $Perl6 && $source =~ m/\G(\s*)(when\b)(?!\s*=>)/gc
147 || $Perl6 && $source =~ m/\G(\s*)(default\b)(?=\s*\{)/gc)
149 my $keyword = $2;
150 $text .= $1 . ($keyword eq "default"
151 ? "if (1)"
152 : "if (Switch::case");
154 if ($keyword eq "default") {
155 # Nothing to do
157 elsif (@pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\{/,qr/\}/,qr/\{/,qr/\}/,undef)) {
158 my $code = substr($source,$pos[0],$pos[4]-$pos[0]);
159 $text .= " " if $pos[0] < $pos[2];
160 $text .= "sub " if is_block $code;
161 $text .= filter_blocks($code,line(substr($source,0,$pos[0]),$line)) . ")";
163 elsif (@pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/[[(]/,qr/[])]/,qr/[[({]/,qr/[])}]/,undef)) {
164 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
165 $code =~ s {^\s*[(]\s*%} { ( \\\%} ||
166 $code =~ s {^\s*[(]\s*m\b} { ( qr} ||
167 $code =~ s {^\s*[(]\s*/} { ( qr/} ||
168 $code =~ s {^\s*[(]\s*qw} { ( \\qw};
169 $text .= " " if $pos[0] < $pos[2];
170 $text .= "$code)";
172 elsif ($Perl6 && do{@pos = Text::Balanced::_match_variable(\$source,qr/\s*/)}) {
173 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
174 $code =~ s {^\s*%} { \%} ||
175 $code =~ s {^\s*@} { \@};
176 $text .= " " if $pos[0] < $pos[2];
177 $text .= "$code)";
179 elsif ( @pos = Text::Balanced::_match_quotelike(\$source,qr/\s*/,1,0)) {
180 my $code = substr($source,$pos[2],$pos[18]-$pos[2]);
181 $code = filter_blocks($code,line(substr($source,0,$pos[2]),$line));
182 $code =~ s {^\s*m} { qr} ||
183 $code =~ s {^\s*/} { qr/} ||
184 $code =~ s {^\s*qw} { \\qw};
185 $text .= " " if $pos[0] < $pos[2];
186 $text .= "$code)";
188 elsif ($Perl5 && $source =~ m/\G\s*(([^\$\@{])[^\$\@{]*)(?=\s*{)/gc
189 || $Perl6 && $source =~ m/\G\s*([^;{]*)()/gc) {
190 my $code = filter_blocks($1,line(substr($source,0,pos $source),$line));
191 $text .= ' \\' if $2 eq '%';
192 $text .= " $code)";
194 else {
195 die "Bad $keyword statement (invalid $keyword value?) near $Switch::file line ", line(substr($source,0,pos $source), $line), "\n";
198 die "Missing opening brace or semi-colon after 'when' value near $Switch::file line ", line(substr($source,0,pos $source), $line), "\n"
199 unless !$Perl6 || $source =~ m/\G(\s*)(?=;|\{)/gc;
201 do{@pos = Text::Balanced::_match_codeblock(\$source,qr/\s*/,qr/\{/,qr/\}/,qr/\{/,qr/\}/,undef)}
202 or do {
203 if ($source =~ m/\G\s*(?=([};]|\Z))/gc) {
204 $casecounter++;
205 next component;
207 die "Bad $keyword statement (problem in the code block?) near $Switch::file line ", line(substr($source,0,pos $source),$line), "\n";
209 my $code = filter_blocks(substr($source,$pos[0],$pos[4]-$pos[0]),line(substr($source,0,$pos[0]),$line));
210 $code =~ s/}(?=\s*\Z)/;last S_W_I_T_C_H }/
211 unless $fallthrough;
212 $text .= "{ while (1) $code continue { goto C_A_S_E_$casecounter } last S_W_I_T_C_H; C_A_S_E_$casecounter: }";
213 $casecounter++;
214 next component;
217 $source =~ m/\G(\s*(-[sm]\s+|\w+|#.*\n|\W))/gc;
218 $text .= $1;
220 $text;
225 sub in
227 my ($x,$y) = @_;
228 my @numy;
229 for my $nextx ( @$x )
231 my $numx = ref($nextx) || defined $nextx && (~$nextx&$nextx) eq 0;
232 for my $j ( 0..$#$y )
234 my $nexty = $y->[$j];
235 push @numy, ref($nexty) || defined $nexty && (~$nexty&$nexty) eq 0
236 if @numy <= $j;
237 return 1 if $numx && $numy[$j] && $nextx==$nexty
238 || $nextx eq $nexty;
242 return "";
245 sub on_exists
247 my $ref = @_==1 && ref($_[0]) eq 'HASH' ? $_[0] : { @_ };
248 [ keys %$ref ]
251 sub on_defined
253 my $ref = @_==1 && ref($_[0]) eq 'HASH' ? $_[0] : { @_ };
254 [ grep { defined $ref->{$_} } keys %$ref ]
257 sub switch(;$)
259 my ($s_val) = @_ ? $_[0] : $_;
260 my $s_ref = ref $s_val;
262 if ($s_ref eq 'CODE')
264 $::_S_W_I_T_C_H =
265 sub { my $c_val = $_[0];
266 return $s_val == $c_val if ref $c_val eq 'CODE';
267 return $s_val->(@$c_val) if ref $c_val eq 'ARRAY';
268 return $s_val->($c_val);
271 elsif ($s_ref eq "" && defined $s_val && (~$s_val&$s_val) eq 0) # NUMERIC SCALAR
273 $::_S_W_I_T_C_H =
274 sub { my $c_val = $_[0];
275 my $c_ref = ref $c_val;
276 return $s_val == $c_val if $c_ref eq ""
277 && defined $c_val
278 && (~$c_val&$c_val) eq 0;
279 return $s_val eq $c_val if $c_ref eq "";
280 return in([$s_val],$c_val) if $c_ref eq 'ARRAY';
281 return $c_val->($s_val) if $c_ref eq 'CODE';
282 return $c_val->call($s_val) if $c_ref eq 'Switch';
283 return scalar $s_val=~/$c_val/
284 if $c_ref eq 'Regexp';
285 return scalar $c_val->{$s_val}
286 if $c_ref eq 'HASH';
287 return;
290 elsif ($s_ref eq "") # STRING SCALAR
292 $::_S_W_I_T_C_H =
293 sub { my $c_val = $_[0];
294 my $c_ref = ref $c_val;
295 return $s_val eq $c_val if $c_ref eq "";
296 return in([$s_val],$c_val) if $c_ref eq 'ARRAY';
297 return $c_val->($s_val) if $c_ref eq 'CODE';
298 return $c_val->call($s_val) if $c_ref eq 'Switch';
299 return scalar $s_val=~/$c_val/
300 if $c_ref eq 'Regexp';
301 return scalar $c_val->{$s_val}
302 if $c_ref eq 'HASH';
303 return;
306 elsif ($s_ref eq 'ARRAY')
308 $::_S_W_I_T_C_H =
309 sub { my $c_val = $_[0];
310 my $c_ref = ref $c_val;
311 return in($s_val,[$c_val]) if $c_ref eq "";
312 return in($s_val,$c_val) if $c_ref eq 'ARRAY';
313 return $c_val->(@$s_val) if $c_ref eq 'CODE';
314 return $c_val->call(@$s_val)
315 if $c_ref eq 'Switch';
316 return scalar grep {$_=~/$c_val/} @$s_val
317 if $c_ref eq 'Regexp';
318 return scalar grep {$c_val->{$_}} @$s_val
319 if $c_ref eq 'HASH';
320 return;
323 elsif ($s_ref eq 'Regexp')
325 $::_S_W_I_T_C_H =
326 sub { my $c_val = $_[0];
327 my $c_ref = ref $c_val;
328 return $c_val=~/s_val/ if $c_ref eq "";
329 return scalar grep {$_=~/s_val/} @$c_val
330 if $c_ref eq 'ARRAY';
331 return $c_val->($s_val) if $c_ref eq 'CODE';
332 return $c_val->call($s_val) if $c_ref eq 'Switch';
333 return $s_val eq $c_val if $c_ref eq 'Regexp';
334 return grep {$_=~/$s_val/ && $c_val->{$_}} keys %$c_val
335 if $c_ref eq 'HASH';
336 return;
339 elsif ($s_ref eq 'HASH')
341 $::_S_W_I_T_C_H =
342 sub { my $c_val = $_[0];
343 my $c_ref = ref $c_val;
344 return $s_val->{$c_val} if $c_ref eq "";
345 return scalar grep {$s_val->{$_}} @$c_val
346 if $c_ref eq 'ARRAY';
347 return $c_val->($s_val) if $c_ref eq 'CODE';
348 return $c_val->call($s_val) if $c_ref eq 'Switch';
349 return grep {$_=~/$c_val/ && $s_val->{"$_"}} keys %$s_val
350 if $c_ref eq 'Regexp';
351 return $s_val==$c_val if $c_ref eq 'HASH';
352 return;
355 elsif ($s_ref eq 'Switch')
357 $::_S_W_I_T_C_H =
358 sub { my $c_val = $_[0];
359 return $s_val == $c_val if ref $c_val eq 'Switch';
360 return $s_val->call(@$c_val)
361 if ref $c_val eq 'ARRAY';
362 return $s_val->call($c_val);
365 else
367 croak "Cannot switch on $s_ref";
369 return 1;
372 sub case($) { local $SIG{__WARN__} = \&carp;
373 $::_S_W_I_T_C_H->(@_); }
375 # IMPLEMENT __
377 my $placeholder = bless { arity=>1, impl=>sub{$_[1+$_[0]]} };
379 sub __() { $placeholder }
381 sub __arg($)
383 my $index = $_[0]+1;
384 bless { arity=>0, impl=>sub{$_[$index]} };
387 sub hosub(&@)
389 # WRITE THIS
392 sub call
394 my ($self,@args) = @_;
395 return $self->{impl}->(0,@args);
398 sub meta_bop(&)
400 my ($op) = @_;
403 my ($left, $right, $reversed) = @_;
404 ($right,$left) = @_ if $reversed;
406 my $rop = ref $right eq 'Switch'
407 ? $right
408 : bless { arity=>0, impl=>sub{$right} };
410 my $lop = ref $left eq 'Switch'
411 ? $left
412 : bless { arity=>0, impl=>sub{$left} };
414 my $arity = $lop->{arity} + $rop->{arity};
416 return bless {
417 arity => $arity,
418 impl => sub { my $start = shift;
419 return $op->($lop->{impl}->($start,@_),
420 $rop->{impl}->($start+$lop->{arity},@_));
426 sub meta_uop(&)
428 my ($op) = @_;
431 my ($left) = @_;
433 my $lop = ref $left eq 'Switch'
434 ? $left
435 : bless { arity=>0, impl=>sub{$left} };
437 my $arity = $lop->{arity};
439 return bless {
440 arity => $arity,
441 impl => sub { $op->($lop->{impl}->(@_)) }
447 use overload
448 "+" => meta_bop {$_[0] + $_[1]},
449 "-" => meta_bop {$_[0] - $_[1]},
450 "*" => meta_bop {$_[0] * $_[1]},
451 "/" => meta_bop {$_[0] / $_[1]},
452 "%" => meta_bop {$_[0] % $_[1]},
453 "**" => meta_bop {$_[0] ** $_[1]},
454 "<<" => meta_bop {$_[0] << $_[1]},
455 ">>" => meta_bop {$_[0] >> $_[1]},
456 "x" => meta_bop {$_[0] x $_[1]},
457 "." => meta_bop {$_[0] . $_[1]},
458 "<" => meta_bop {$_[0] < $_[1]},
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 "lt" => meta_bop {$_[0] lt $_[1]},
466 "le" => meta_bop {$_[0] le $_[1]},
467 "gt" => meta_bop {$_[0] gt $_[1]},
468 "ge" => meta_bop {$_[0] ge $_[1]},
469 "eq" => meta_bop {$_[0] eq $_[1]},
470 "ne" => meta_bop {$_[0] ne $_[1]},
471 "cmp" => meta_bop {$_[0] cmp $_[1]},
472 "\&" => meta_bop {$_[0] & $_[1]},
473 "^" => meta_bop {$_[0] ^ $_[1]},
474 "|" => meta_bop {$_[0] | $_[1]},
475 "atan2" => meta_bop {atan2 $_[0], $_[1]},
477 "neg" => meta_uop {-$_[0]},
478 "!" => meta_uop {!$_[0]},
479 "~" => meta_uop {~$_[0]},
480 "cos" => meta_uop {cos $_[0]},
481 "sin" => meta_uop {sin $_[0]},
482 "exp" => meta_uop {exp $_[0]},
483 "abs" => meta_uop {abs $_[0]},
484 "log" => meta_uop {log $_[0]},
485 "sqrt" => meta_uop {sqrt $_[0]},
486 "bool" => sub { croak "Can't use && or || in expression containing __" },
488 # "&()" => sub { $_[0]->{impl} },
490 # "||" => meta_bop {$_[0] || $_[1]},
491 # "&&" => meta_bop {$_[0] && $_[1]},
492 # fallback => 1,
496 __END__
499 =head1 NAME
501 Switch - A switch statement for Perl
503 =head1 VERSION
505 This document describes version 2.10 of Switch,
506 released Dec 29, 2003.
508 =head1 SYNOPSIS
510 use Switch;
512 switch ($val) {
514 case 1 { print "number 1" }
515 case "a" { print "string a" }
516 case [1..10,42] { print "number in list" }
517 case (@array) { print "number in list" }
518 case /\w+/ { print "pattern" }
519 case qr/\w+/ { print "pattern" }
520 case (%hash) { print "entry in hash" }
521 case (\%hash) { print "entry in hash" }
522 case (\&sub) { print "arg to subroutine" }
523 else { print "previous case not true" }
526 =head1 BACKGROUND
528 [Skip ahead to L<"DESCRIPTION"> if you don't care about the whys
529 and wherefores of this control structure]
531 In seeking to devise a "Swiss Army" case mechanism suitable for Perl,
532 it is useful to generalize this notion of distributed conditional
533 testing as far as possible. Specifically, the concept of "matching"
534 between the switch value and the various case values need not be
535 restricted to numeric (or string or referential) equality, as it is in other
536 languages. Indeed, as Table 1 illustrates, Perl
537 offers at least eighteen different ways in which two values could
538 generate a match.
540 Table 1: Matching a switch value ($s) with a case value ($c)
542 Switch Case Type of Match Implied Matching Code
543 Value Value
544 ====== ===== ===================== =============
546 number same numeric or referential match if $s == $c;
547 or ref equality
549 object method result of method call match if $s->$c();
550 ref name match if defined $s->$c();
551 or ref
553 other other string equality match if $s eq $c;
554 non-ref non-ref
555 scalar scalar
557 string regexp pattern match match if $s =~ /$c/;
559 array scalar array entry existence match if 0<=$c && $c<@$s;
560 ref array entry definition match if defined $s->[$c];
561 array entry truth match if $s->[$c];
563 array array array intersection match if intersects(@$s, @$c);
564 ref ref (apply this table to
565 all pairs of elements
566 $s->[$i] and
567 $c->[$j])
569 array regexp array grep match if grep /$c/, @$s;
570 ref
572 hash scalar hash entry existence match if exists $s->{$c};
573 ref hash entry definition match if defined $s->{$c};
574 hash entry truth match if $s->{$c};
576 hash regexp hash grep match if grep /$c/, keys %$s;
577 ref
579 sub scalar return value defn match if defined $s->($c);
580 ref return value truth match if $s->($c);
582 sub array return value defn match if defined $s->(@$c);
583 ref ref return value truth match if $s->(@$c);
586 In reality, Table 1 covers 31 alternatives, because only the equality and
587 intersection tests are commutative; in all other cases, the roles of
588 the C<$s> and C<$c> variables could be reversed to produce a
589 different test. For example, instead of testing a single hash for
590 the existence of a series of keys (C<match if exists $s-E<gt>{$c}>),
591 one could test for the existence of a single key in a series of hashes
592 (C<match if exists $c-E<gt>{$s}>).
594 As L<perltodo> observes, a Perl case mechanism must support all these
595 "ways to do it".
598 =head1 DESCRIPTION
600 The Switch.pm module implements a generalized case mechanism that covers
601 the numerous possible combinations of switch and case values described above.
603 The module augments the standard Perl syntax with two new control
604 statements: C<switch> and C<case>. The C<switch> statement takes a
605 single scalar argument of any type, specified in parentheses.
606 C<switch> stores this value as the
607 current switch value in a (localized) control variable.
608 The value is followed by a block which may contain one or more
609 Perl statements (including the C<case> statement described below).
610 The block is unconditionally executed once the switch value has
611 been cached.
613 A C<case> statement takes a single scalar argument (in mandatory
614 parentheses if it's a variable; otherwise the parens are optional) and
615 selects the appropriate type of matching between that argument and the
616 current switch value. The type of matching used is determined by the
617 respective types of the switch value and the C<case> argument, as
618 specified in Table 1. If the match is successful, the mandatory
619 block associated with the C<case> statement is executed.
621 In most other respects, the C<case> statement is semantically identical
622 to an C<if> statement. For example, it can be followed by an C<else>
623 clause, and can be used as a postfix statement qualifier.
625 However, when a C<case> block has been executed control is automatically
626 transferred to the statement after the immediately enclosing C<switch>
627 block, rather than to the next statement within the block. In other
628 words, the success of any C<case> statement prevents other cases in the
629 same scope from executing. But see L<"Allowing fall-through"> below.
631 Together these two new statements provide a fully generalized case
632 mechanism:
634 use Switch;
636 # AND LATER...
638 %special = ( woohoo => 1, d'oh => 1 );
640 while (<>) {
641 switch ($_) {
643 case (%special) { print "homer\n"; } # if $special{$_}
644 case /a-z/i { print "alpha\n"; } # if $_ =~ /a-z/i
645 case [1..9] { print "small num\n"; } # if $_ in [1..9]
647 case { $_[0] >= 10 } { # if $_ >= 10
648 my $age = <>;
649 switch (sub{ $_[0] < $age } ) {
651 case 20 { print "teens\n"; } # if 20 < $age
652 case 30 { print "twenties\n"; } # if 30 < $age
653 else { print "history\n"; }
657 print "must be punctuation\n" case /\W/; # if $_ ~= /\W/
660 Note that C<switch>es can be nested within C<case> (or any other) blocks,
661 and a series of C<case> statements can try different types of matches
662 -- hash membership, pattern match, array intersection, simple equality,
663 etc. -- against the same switch value.
665 The use of intersection tests against an array reference is particularly
666 useful for aggregating integral cases:
668 sub classify_digit
670 switch ($_[0]) { case 0 { return 'zero' }
671 case [2,4,6,8] { return 'even' }
672 case [1,3,4,7,9] { return 'odd' }
673 case /[A-F]/i { return 'hex' }
678 =head2 Allowing fall-through
680 Fall-though (trying another case after one has already succeeded)
681 is usually a Bad Idea in a switch statement. However, this
682 is Perl, not a police state, so there I<is> a way to do it, if you must.
684 If a C<case> block executes an untargeted C<next>, control is
685 immediately transferred to the statement I<after> the C<case> statement
686 (i.e. usually another case), rather than out of the surrounding
687 C<switch> block.
689 For example:
691 switch ($val) {
692 case 1 { handle_num_1(); next } # and try next case...
693 case "1" { handle_str_1(); next } # and try next case...
694 case [0..9] { handle_num_any(); } # and we're done
695 case /\d/ { handle_dig_any(); next } # and try next case...
696 case /.*/ { handle_str_any(); next } # and try next case...
699 If $val held the number C<1>, the above C<switch> block would call the
700 first three C<handle_...> subroutines, jumping to the next case test
701 each time it encountered a C<next>. After the thrid C<case> block
702 was executed, control would jump to the end of the enclosing
703 C<switch> block.
705 On the other hand, if $val held C<10>, then only the last two C<handle_...>
706 subroutines would be called.
708 Note that this mechanism allows the notion of I<conditional fall-through>.
709 For example:
711 switch ($val) {
712 case [0..9] { handle_num_any(); next if $val < 7; }
713 case /\d/ { handle_dig_any(); }
716 If an untargeted C<last> statement is executed in a case block, this
717 immediately transfers control out of the enclosing C<switch> block
718 (in other words, there is an implicit C<last> at the end of each
719 normal C<case> block). Thus the previous example could also have been
720 written:
722 switch ($val) {
723 case [0..9] { handle_num_any(); last if $val >= 7; next; }
724 case /\d/ { handle_dig_any(); }
728 =head2 Automating fall-through
730 In situations where case fall-through should be the norm, rather than an
731 exception, an endless succession of terminal C<next>s is tedious and ugly.
732 Hence, it is possible to reverse the default behaviour by specifying
733 the string "fallthrough" when importing the module. For example, the
734 following code is equivalent to the first example in L<"Allowing fall-through">:
736 use Switch 'fallthrough';
738 switch ($val) {
739 case 1 { handle_num_1(); }
740 case "1" { handle_str_1(); }
741 case [0..9] { handle_num_any(); last }
742 case /\d/ { handle_dig_any(); }
743 case /.*/ { handle_str_any(); }
746 Note the explicit use of a C<last> to preserve the non-fall-through
747 behaviour of the third case.
751 =head2 Alternative syntax
753 Perl 6 will provide a built-in switch statement with essentially the
754 same semantics as those offered by Switch.pm, but with a different
755 pair of keywords. In Perl 6 C<switch> will be spelled C<given>, and
756 C<case> will be pronounced C<when>. In addition, the C<when> statement
757 will not require switch or case values to be parenthesized.
759 This future syntax is also (largely) available via the Switch.pm module, by
760 importing it with the argument C<"Perl6">. For example:
762 use Switch 'Perl6';
764 given ($val) {
765 when 1 { handle_num_1(); }
766 when ($str1) { handle_str_1(); }
767 when [0..9] { handle_num_any(); last }
768 when /\d/ { handle_dig_any(); }
769 when /.*/ { handle_str_any(); }
770 default { handle anything else; }
773 Note that scalars still need to be parenthesized, since they would be
774 ambiguous in Perl 5.
776 Note too that you can mix and match both syntaxes by importing the module
777 with:
779 use Switch 'Perl5', 'Perl6';
782 =head2 Higher-order Operations
784 One situation in which C<switch> and C<case> do not provide a good
785 substitute for a cascaded C<if>, is where a switch value needs to
786 be tested against a series of conditions. For example:
788 sub beverage {
789 switch (shift) {
791 case sub { $_[0] < 10 } { return 'milk' }
792 case sub { $_[0] < 20 } { return 'coke' }
793 case sub { $_[0] < 30 } { return 'beer' }
794 case sub { $_[0] < 40 } { return 'wine' }
795 case sub { $_[0] < 50 } { return 'malt' }
796 case sub { $_[0] < 60 } { return 'Moet' }
797 else { return 'milk' }
801 The need to specify each condition as a subroutine block is tiresome. To
802 overcome this, when importing Switch.pm, a special "placeholder"
803 subroutine named C<__> [sic] may also be imported. This subroutine
804 converts (almost) any expression in which it appears to a reference to a
805 higher-order function. That is, the expression:
807 use Switch '__';
809 __ < 2 + __
811 is equivalent to:
813 sub { $_[0] < 2 + $_[1] }
815 With C<__>, the previous ugly case statements can be rewritten:
817 case __ < 10 { return 'milk' }
818 case __ < 20 { return 'coke' }
819 case __ < 30 { return 'beer' }
820 case __ < 40 { return 'wine' }
821 case __ < 50 { return 'malt' }
822 case __ < 60 { return 'Moet' }
823 else { return 'milk' }
825 The C<__> subroutine makes extensive use of operator overloading to
826 perform its magic. All operations involving __ are overloaded to
827 produce an anonymous subroutine that implements a lazy version
828 of the original operation.
830 The only problem is that operator overloading does not allow the
831 boolean operators C<&&> and C<||> to be overloaded. So a case statement
832 like this:
834 case 0 <= __ && __ < 10 { return 'digit' }
836 doesn't act as expected, because when it is
837 executed, it constructs two higher order subroutines
838 and then treats the two resulting references as arguments to C<&&>:
840 sub { 0 <= $_[0] } && sub { $_[0] < 10 }
842 This boolean expression is inevitably true, since both references are
843 non-false. Fortunately, the overloaded C<'bool'> operator catches this
844 situation and flags it as a error.
846 =head1 DEPENDENCIES
848 The module is implemented using Filter::Util::Call and Text::Balanced
849 and requires both these modules to be installed.
851 =head1 AUTHOR
853 Damian Conway (damian@conway.org). The maintainer of this module is now Rafael
854 Garcia-Suarez (rgarciasuarez@free.fr).
856 =head1 BUGS
858 There are undoubtedly serious bugs lurking somewhere in code this funky :-)
859 Bug reports and other feedback are most welcome.
861 =head1 LIMITATIONS
863 Due to the heuristic nature of Switch.pm's source parsing, the presence
864 of regexes specified with raw C<?...?> delimiters may cause mysterious
865 errors. The workaround is to use C<m?...?> instead.
867 Due to the way source filters work in Perl, you can't use Switch inside
868 an string C<eval>.
870 If your source file is longer then 1 million characters and you have a
871 switch statement that crosses the 1 million (or 2 million, etc.)
872 character boundary you will get mysterious errors. The workaround is to
873 use smaller source files.
875 =head1 COPYRIGHT
877 Copyright (c) 1997-2003, Damian Conway. All Rights Reserved.
878 This module is free software. It may be used, redistributed
879 and/or modified under the same terms as Perl itself.