1Syntax::Keyword::Match(U3spemr)Contributed Perl DocumentSaytnitoanx::Keyword::Match(3pm)
2
3
4

NAME

6       "Syntax::Keyword::Match" - a "match/case" syntax for perl
7

SYNOPSIS

9          use v5.14;
10          use Syntax::Keyword::Match;
11
12          my $n = ...;
13
14          match($n : ==) {
15             case(1) { say "It's one" }
16             case(2) { say "It's two" }
17             case(3) { say "It's three" }
18             case(4), case(5)
19                     { say "It's four or five" }
20             case if($n < 10)
21                     { say "It's less than ten" }
22             default { say "It's something else" }
23          }
24

DESCRIPTION

26       This module provides a syntax plugin that implements a control-flow
27       block called "match/case", which executes at most one of a choice of
28       different blocks depending on the value of its controlling expression.
29
30       This is similar to C's "switch/case" syntax (copied into many other
31       languages), or syntax provided by Switch::Plain.
32
33       This is an initial, experimental implementation. Furthermore, it is
34       built as a non-trivial example use-case on top of XS::Parse::Keyword,
35       which is also experimental. No API or compatibility guarantees are made
36       at this time.
37

Experimental Features

39       Some of the features of this module are currently marked as
40       experimental (even within the context that the module itself is
41       experimental). They will provoke warnings in the "experimental"
42       category, unless silenced.
43
44          use Syntax::Keyword::Match qw( match :experimental(dispatch) );
45
46          use Syntax::Keyword::Match qw( match :experimental );  # all of the above
47

KEYWORDS

49   match
50          match( EXPR : OP ) {
51             ...
52          }
53
54       A "match" statement provides the controlling expression, comparison
55       operator, and sequence of "case" statements for a match operation. The
56       expression is evaluated to yield a scalar value, which is then
57       compared, using the comparison operator, against each of the "case"
58       labels in the order they are written, topmost first. If a match is
59       found then the body of the labelled block is executed. If no label
60       matches but a "default" block is present, that will be executed
61       instead. After a single inner block has been executed, no further tests
62       are performed and execution continues from the statement following the
63       "match" statement.
64
65       The braces following the "match" block must only contain "case" or
66       "default" statements. Arbitrary code is not supported here.
67
68       Even though a "match" statement is a full statement and not an
69       expression, it can still yield a value if it appears as the final
70       statment in its containing "sub" or "do" block. For example:
71
72          my $result = do {
73             match( $topic : == ) {
74                case(1) { ... }
75             }
76          };
77
78       If the controlling expression introduces a new variable, that variable
79       will be visible within any of the "case" blocks, and will go out of
80       scope after the "match" statement finishes. This may be useful for
81       temporarily storing the result of a more complex expression.
82
83          match( my $x = some_function_call() : == ) {
84             case ...
85          }
86
87       Comparison Operators
88
89       The comparison operator must be either "eq" (to compare cases as
90       strings) or "==" (to compare them as numbers), or "=~" (to compare
91       cases using regexps).
92
93       Since version 0.11 on any Perl release, or previous versions on Perl
94       releases 5.32 onwards, the "isa" operator is also supported, allowing
95       dispatch based on what type of object the controlling expression gives.
96
97          match( $obj : isa ) {
98             case(A::Package)       { ... }
99             case(Another::Package) { ... }
100          }
101
102       Remember that comparisons are made in the order they are written, from
103       the top downwards. Therefore, if you list a derived class as well as a
104       base class, make sure to put the derived class before the base class,
105       or instances of that type will also match the base class "case" block
106       and the derived one will never match.
107
108          class TheBase {}
109          class Derived :isa(TheBase) {}
110
111          match( $obj : isa ) {
112             case(TheBase) { ... }
113             case(Derived) {
114                # This case will never match as the one above will always happen first
115             }
116          }
117
118       Since version 0.08 the operator syntax is parsed using
119       XS::Parse::Infix, meaning that custom infix operators can be
120       recognised, even on versions of perl that do not support the full
121       "PL_infix_plugin" mechanism.
122
123   case
124          case(VAL) { STATEMENTS... }
125
126          case(VAL), case(VAL), ... { STATEMENTS... }
127
128       A "case" statement must only appear inside the braces of a "match". It
129       provides a block of code to run if the controlling expression's value
130       matches the value given in the "case" statement, according to the
131       comparison operator.
132
133       Multiple "case" statements are permitted for a single block. A value
134       matching any of them will run the code inside the block.
135
136       If the value is a non-constant expression, such as a variable or
137       function call, it will be evaluated as part of performing the
138       comparison every time the "match" statement is executed. For best
139       performance it is advised to extract values that won't need computing
140       again into a variable or "use constant" that can be calculated just
141       once at program startup; for example:
142
143          use constant CONDITION => a_function("with", "arguments");
144
145          match( $var : eq ) {
146             case(CONDITION) { ... }
147             ...
148          }
149
150       The :experimental(dispatch) feature selects a more efficient handling
151       of sequences of multiple "case" blocks with constant expressions. This
152       handling is implemented with a custom operator that will entirely
153       confuse modules like "B::Deparse" or optree inspectors like coverage
154       tools so is not selected by default, but can be enabled for extra
155       performance in critical sections.
156
157   case if
158          case if(EXPR) { STATEMENTS... }
159
160          case(VAL), case if(EXPR) { STATEMENTS... }
161
162       A "case" statement may also be written "case if" with a boolean
163       predicate expression in parentheses. This inserts a direct boolean test
164       into the comparison logic, allowing for other logical tests that aren't
165       easily expressed as uses of the comparison operator. As "case if" is an
166       alternative to a regular "case", they can be combined on a single code
167       block if required.
168
169       For example, when testing an inequality in a selection of numerical
170       "==" tests, or a single regexp test among some string "eq" tests.
171
172          match( $num : == ) {
173             case(0)           { ... }
174             case(1), case(2)  { ... }
175             case if($num < 5) { ... }
176          }
177
178          match( $str : eq ) {
179             case("abc")           { ... }
180             case("def")           { ... }
181             case if($str =~ m/g/) { ... }
182          }
183
184       By default the match value is not assigned into a variable that is
185       visible to "case if" expressions, but if needed a new lexical can be
186       constructed by using a regular "my" assignment.
187
188          match( my $v = some_expression() : eq ) {
189             case if($v =~ m/pattern/) { ... }
190          }
191
192   default
193       A "default" statement must only appear inside the braces of a "match".
194       If present, it must be the final choice, and there must only be one of
195       them. It provides a block of code to run if the controlling
196       expression's value did not match any of the given "case" labels.
197

COMPARISONS

199       As this syntax is fairly similar to a few other ideas, the following
200       comparisons may be useful.
201
202   Core perl's given/when syntax
203       Compared to core perl's "given/when" syntax (available with "use
204       feature 'switch'"), this syntax is initially visually very similar but
205       actually behaves very differently. Core's "given/when" uses the
206       smartmatch ("~~") operator for its comparisons, which is complex,
207       subtle, and hard to use correctly - doubly-so when comparisons against
208       values stored in variables rather than literal constants are involved.
209       It can be unpredictable whether string or numerical comparison are
210       being used, for example. By comparison, this module requires the
211       programmer to specify the comparison operator. The choice of string or
212       numerical comparison is given in the source code - there can be no
213       ambiguity.
214
215       Additionally, the "isa" operator is also permitted, which has no
216       equivalent ability in smartmatch.
217
218       Also, the "given/when" syntax permits mixed code within a "given" block
219       which is run unconditionally, or at least, until the first successful
220       "when" statement is encountered. The syntax provided by this module
221       requires that the only code inside a "match" block be a sequence of
222       "case" statements. No other code is permitted.
223
224   Switch::Plain
225       Like this module, Switch::Plain also provides a syntax where the
226       programmer specifies whether the comparison is made using stringy or
227       numerical semantics.  "Switch::Plain" also permits additional
228       conditions to be placed on "case" blocks, whereas this module does not.
229
230       Additionally, the "isa" operator is also permitted, which has no
231       equivalent ability in "Switch::Plain".
232
233   C's switch/case
234       The C programming language provides a similar sort of syntax, using
235       keywords named "switch" and "case". One key difference between that and
236       the syntax provided for Perl by this module is that in C the "case"
237       labels really are just labels. The "switch" part of the statement
238       effectively acts as a sort of computed "goto". This often leads to bugs
239       caused by forgetting to put a "break" at the end of a sequence of
240       statements before the next "case" label; a situation called
241       "fallthrough". Such a mistake is impossible with this module, because
242       every "case" is provided by a block. Once execution has finished with
243       the block, the entire "match" statement is finished. There is no
244       possibility of accidental fallthrough.
245
246       C's syntax only permits compiletime constants for "case" labels,
247       whereas this module will also allow the result of any runtime
248       expression.
249
250       Code written in C will perform identically even if any of the "case"
251       labels and associated code are moved around into a different order. The
252       syntax provided by this module notionally performs all of its tests in
253       the order they are written in, and any changes of that order might
254       cause a different result.
255

TODO

257       This is clearly an early experimental work. There are many features to
258       add, and design decisions to make. Rather than attempt to list them all
259       here it would be best to check the RT bug queue at
260
261       <https://rt.cpan.org/Dist/Display.html?Name=Syntax-Keyword-Match>
262

AUTHOR

264       Paul Evans <leonerd@leonerd.org.uk>
265
266
267
268perl v5.38.0                      2023-07-26       Syntax::Keyword::Match(3pm)
Impressum