1Switch(3pm) Perl Programmers Reference Guide Switch(3pm)
2
3
4
6 Switch - A switch statement for Perl
7
9 This document describes version 2.10 of Switch, released Dec 29, 2003.
10
12 use Switch;
13
14 switch ($val) {
15
16 case 1 { print "number 1" }
17 case "a" { print "string a" }
18 case [1..10,42] { print "number in list" }
19 case (@array) { print "number in list" }
20 case /\w+/ { print "pattern" }
21 case qr/\w+/ { print "pattern" }
22 case (%hash) { print "entry in hash" }
23 case (\%hash) { print "entry in hash" }
24 case (\&sub) { print "arg to subroutine" }
25 else { print "previous case not true" }
26 }
27
29 [Skip ahead to "DESCRIPTION" if you don't care about the whys and
30 wherefores of this control structure]
31
32 In seeking to devise a "Swiss Army" case mechanism suitable for Perl,
33 it is useful to generalize this notion of distributed conditional test‐
34 ing as far as possible. Specifically, the concept of "matching" between
35 the switch value and the various case values need not be restricted to
36 numeric (or string or referential) equality, as it is in other lan‐
37 guages. Indeed, as Table 1 illustrates, Perl offers at least eighteen
38 different ways in which two values could generate a match.
39
40 Table 1: Matching a switch value ($s) with a case value ($c)
41
42 Switch Case Type of Match Implied Matching Code
43 Value Value
44 ====== ===== ===================== =============
45
46 number same numeric or referential match if $s == $c;
47 or ref equality
48
49 object method result of method call match if $s->$c();
50 ref name match if defined $s->$c();
51 or ref
52
53 other other string equality match if $s eq $c;
54 non-ref non-ref
55 scalar scalar
56
57 string regexp pattern match match if $s =~ /$c/;
58
59 array scalar array entry existence match if 0<=$c && $c<@$s;
60 ref array entry definition match if defined $s->[$c];
61 array entry truth match if $s->[$c];
62
63 array array array intersection match if intersects(@$s, @$c);
64 ref ref (apply this table to
65 all pairs of elements
66 $s->[$i] and
67 $c->[$j])
68
69 array regexp array grep match if grep /$c/, @$s;
70 ref
71
72 hash scalar hash entry existence match if exists $s->{$c};
73 ref hash entry definition match if defined $s->{$c};
74 hash entry truth match if $s->{$c};
75
76 hash regexp hash grep match if grep /$c/, keys %$s;
77 ref
78
79 sub scalar return value defn match if defined $s->($c);
80 ref return value truth match if $s->($c);
81
82 sub array return value defn match if defined $s->(@$c);
83 ref ref return value truth match if $s->(@$c);
84
85 In reality, Table 1 covers 31 alternatives, because only the equality
86 and intersection tests are commutative; in all other cases, the roles
87 of the $s and $c variables could be reversed to produce a different
88 test. For example, instead of testing a single hash for the existence
89 of a series of keys ("match if exists $s->{$c}"), one could test for
90 the existence of a single key in a series of hashes ("match if exists
91 $c->{$s}").
92
93 As perltodo observes, a Perl case mechanism must support all these
94 "ways to do it".
95
97 The Switch.pm module implements a generalized case mechanism that cov‐
98 ers the numerous possible combinations of switch and case values
99 described above.
100
101 The module augments the standard Perl syntax with two new control
102 statements: "switch" and "case". The "switch" statement takes a single
103 scalar argument of any type, specified in parentheses. "switch" stores
104 this value as the current switch value in a (localized) control vari‐
105 able. The value is followed by a block which may contain one or more
106 Perl statements (including the "case" statement described below). The
107 block is unconditionally executed once the switch value has been
108 cached.
109
110 A "case" statement takes a single scalar argument (in mandatory paren‐
111 theses if it's a variable; otherwise the parens are optional) and
112 selects the appropriate type of matching between that argument and the
113 current switch value. The type of matching used is determined by the
114 respective types of the switch value and the "case" argument, as speci‐
115 fied in Table 1. If the match is successful, the mandatory block asso‐
116 ciated with the "case" statement is executed.
117
118 In most other respects, the "case" statement is semantically identical
119 to an "if" statement. For example, it can be followed by an "else"
120 clause, and can be used as a postfix statement qualifier.
121
122 However, when a "case" block has been executed control is automatically
123 transferred to the statement after the immediately enclosing "switch"
124 block, rather than to the next statement within the block. In other
125 words, the success of any "case" statement prevents other cases in the
126 same scope from executing. But see "Allowing fall-through" below.
127
128 Together these two new statements provide a fully generalized case
129 mechanism:
130
131 use Switch;
132
133 # AND LATER...
134
135 %special = ( woohoo => 1, d'oh => 1 );
136
137 while (<>) {
138 switch ($_) {
139
140 case (%special) { print "homer\n"; } # if $special{$_}
141 case /a-z/i { print "alpha\n"; } # if $_ =~ /a-z/i
142 case [1..9] { print "small num\n"; } # if $_ in [1..9]
143
144 case { $_[0] >= 10 } { # if $_ >= 10
145 my $age = <>;
146 switch (sub{ $_[0] < $age } ) {
147
148 case 20 { print "teens\n"; } # if 20 < $age
149 case 30 { print "twenties\n"; } # if 30 < $age
150 else { print "history\n"; }
151 }
152 }
153
154 print "must be punctuation\n" case /\W/; # if $_ ~= /\W/
155 }
156
157 Note that "switch"es can be nested within "case" (or any other) blocks,
158 and a series of "case" statements can try different types of matches --
159 hash membership, pattern match, array intersection, simple equality,
160 etc. -- against the same switch value.
161
162 The use of intersection tests against an array reference is particu‐
163 larly useful for aggregating integral cases:
164
165 sub classify_digit
166 {
167 switch ($_[0]) { case 0 { return 'zero' }
168 case [2,4,6,8] { return 'even' }
169 case [1,3,4,7,9] { return 'odd' }
170 case /[A-F]/i { return 'hex' }
171 }
172 }
173
174 Allowing fall-through
175
176 Fall-though (trying another case after one has already succeeded) is
177 usually a Bad Idea in a switch statement. However, this is Perl, not a
178 police state, so there is a way to do it, if you must.
179
180 If a "case" block executes an untargeted "next", control is immediately
181 transferred to the statement after the "case" statement (i.e. usually
182 another case), rather than out of the surrounding "switch" block.
183
184 For example:
185
186 switch ($val) {
187 case 1 { handle_num_1(); next } # and try next case...
188 case "1" { handle_str_1(); next } # and try next case...
189 case [0..9] { handle_num_any(); } # and we're done
190 case /\d/ { handle_dig_any(); next } # and try next case...
191 case /.*/ { handle_str_any(); next } # and try next case...
192 }
193
194 If $val held the number 1, the above "switch" block would call the
195 first three "handle_..." subroutines, jumping to the next case test
196 each time it encountered a "next". After the thrid "case" block was
197 executed, control would jump to the end of the enclosing "switch"
198 block.
199
200 On the other hand, if $val held 10, then only the last two "handle_..."
201 subroutines would be called.
202
203 Note that this mechanism allows the notion of conditional fall-through.
204 For example:
205
206 switch ($val) {
207 case [0..9] { handle_num_any(); next if $val < 7; }
208 case /\d/ { handle_dig_any(); }
209 }
210
211 If an untargeted "last" statement is executed in a case block, this
212 immediately transfers control out of the enclosing "switch" block (in
213 other words, there is an implicit "last" at the end of each normal
214 "case" block). Thus the previous example could also have been written:
215
216 switch ($val) {
217 case [0..9] { handle_num_any(); last if $val >= 7; next; }
218 case /\d/ { handle_dig_any(); }
219 }
220
221 Automating fall-through
222
223 In situations where case fall-through should be the norm, rather than
224 an exception, an endless succession of terminal "next"s is tedious and
225 ugly. Hence, it is possible to reverse the default behaviour by speci‐
226 fying the string "fallthrough" when importing the module. For example,
227 the following code is equivalent to the first example in "Allowing
228 fall-through":
229
230 use Switch 'fallthrough';
231
232 switch ($val) {
233 case 1 { handle_num_1(); }
234 case "1" { handle_str_1(); }
235 case [0..9] { handle_num_any(); last }
236 case /\d/ { handle_dig_any(); }
237 case /.*/ { handle_str_any(); }
238 }
239
240 Note the explicit use of a "last" to preserve the non-fall-through be‐
241 haviour of the third case.
242
243 Alternative syntax
244
245 Perl 6 will provide a built-in switch statement with essentially the
246 same semantics as those offered by Switch.pm, but with a different pair
247 of keywords. In Perl 6 "switch" will be spelled "given", and "case"
248 will be pronounced "when". In addition, the "when" statement will not
249 require switch or case values to be parenthesized.
250
251 This future syntax is also (largely) available via the Switch.pm mod‐
252 ule, by importing it with the argument "Perl6". For example:
253
254 use Switch 'Perl6';
255
256 given ($val) {
257 when 1 { handle_num_1(); }
258 when ($str1) { handle_str_1(); }
259 when [0..9] { handle_num_any(); last }
260 when /\d/ { handle_dig_any(); }
261 when /.*/ { handle_str_any(); }
262 default { handle anything else; }
263 }
264
265 Note that scalars still need to be parenthesized, since they would be
266 ambiguous in Perl 5.
267
268 Note too that you can mix and match both syntaxes by importing the mod‐
269 ule with:
270
271 use Switch 'Perl5', 'Perl6';
272
273 Higher-order Operations
274
275 One situation in which "switch" and "case" do not provide a good sub‐
276 stitute for a cascaded "if", is where a switch value needs to be tested
277 against a series of conditions. For example:
278
279 sub beverage {
280 switch (shift) {
281
282 case sub { $_[0] < 10 } { return 'milk' }
283 case sub { $_[0] < 20 } { return 'coke' }
284 case sub { $_[0] < 30 } { return 'beer' }
285 case sub { $_[0] < 40 } { return 'wine' }
286 case sub { $_[0] < 50 } { return 'malt' }
287 case sub { $_[0] < 60 } { return 'Moet' }
288 else { return 'milk' }
289 }
290 }
291
292 The need to specify each condition as a subroutine block is tiresome.
293 To overcome this, when importing Switch.pm, a special "placeholder"
294 subroutine named "__" [sic] may also be imported. This subroutine con‐
295 verts (almost) any expression in which it appears to a reference to a
296 higher-order function. That is, the expression:
297
298 use Switch '__';
299
300 __ < 2 + __
301
302 is equivalent to:
303
304 sub { $_[0] < 2 + $_[1] }
305
306 With "__", the previous ugly case statements can be rewritten:
307
308 case __ < 10 { return 'milk' }
309 case __ < 20 { return 'coke' }
310 case __ < 30 { return 'beer' }
311 case __ < 40 { return 'wine' }
312 case __ < 50 { return 'malt' }
313 case __ < 60 { return 'Moet' }
314 else { return 'milk' }
315
316 The "__" subroutine makes extensive use of operator overloading to per‐
317 form its magic. All operations involving __ are overloaded to produce
318 an anonymous subroutine that implements a lazy version of the original
319 operation.
320
321 The only problem is that operator overloading does not allow the bool‐
322 ean operators "&&" and "⎪⎪" to be overloaded. So a case statement like
323 this:
324
325 case 0 <= __ && __ < 10 { return 'digit' }
326
327 doesn't act as expected, because when it is executed, it constructs two
328 higher order subroutines and then treats the two resulting references
329 as arguments to "&&":
330
331 sub { 0 <= $_[0] } && sub { $_[0] < 10 }
332
333 This boolean expression is inevitably true, since both references are
334 non-false. Fortunately, the overloaded 'bool' operator catches this
335 situation and flags it as a error.
336
338 The module is implemented using Filter::Util::Call and Text::Balanced
339 and requires both these modules to be installed.
340
342 Damian Conway (damian@conway.org). The maintainer of this module is now
343 Rafael Garcia-Suarez (rgarciasuarez@free.fr).
344
346 There are undoubtedly serious bugs lurking somewhere in code this funky
347 :-) Bug reports and other feedback are most welcome.
348
350 Due to the heuristic nature of Switch.pm's source parsing, the presence
351 of regexes specified with raw "?...?" delimiters may cause mysterious
352 errors. The workaround is to use "m?...?" instead.
353
354 Due to the way source filters work in Perl, you can't use Switch inside
355 an string "eval".
356
357 If your source file is longer then 1 million characters and you have a
358 switch statement that crosses the 1 million (or 2 million, etc.) char‐
359 acter boundary you will get mysterious errors. The workaround is to use
360 smaller source files.
361
363 Copyright (c) 1997-2003, Damian Conway. All Rights Reserved.
364 This module is free software. It may be used, redistributed
365 and/or modified under the same terms as Perl itself.
366
367
368
369perl v5.8.8 2001-09-21 Switch(3pm)