File Coverage

blib/lib/Syntax/Keyword/Try.pm
Criterion Covered Total %
statement 28 30 93.3
branch 14 18 77.7
condition 1 3 33.3
subroutine 5 5 100.0
pod 0 1 0.0
total 48 57 84.2


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2016-2022 -- leonerd@leonerd.org.uk
5              
6             package Syntax::Keyword::Try 0.28;
7              
8 15     15   947169 use v5.14;
  15         193  
9 15     15   83 use warnings;
  15         31  
  15         385  
10              
11 15     15   75 use Carp;
  15         28  
  15         7956  
12              
13             require XSLoader;
14             XSLoader::load( __PACKAGE__, our $VERSION );
15              
16             =head1 NAME
17              
18             C - a C syntax for perl
19              
20             =head1 SYNOPSIS
21              
22             use Syntax::Keyword::Try;
23              
24             sub foo {
25             try {
26             attempt_a_thing();
27             return "success";
28             }
29             catch ($e) {
30             warn "It failed - $e";
31             return "failure";
32             }
33             }
34              
35             =head1 DESCRIPTION
36              
37             This module provides a syntax plugin that implements exception-handling
38             semantics in a form familiar to users of other languages, being built on a
39             block labeled with the C keyword, followed by at least one of a C
40             or C block.
41              
42             As well as providing a handy syntax for this useful behaviour, this module
43             also serves to contain a number of code examples for how to implement parser
44             plugins and manipulate optrees to provide new syntax and behaviours for perl
45             code.
46              
47             Syntax similar to this module has now been added to core perl, starting at
48             version 5.34.0. If you are writing new code, it is suggested that you instead
49             use the L module instead, as that will enable the core
50             feature on those supported perl versions, falling back to
51             C on older perls.
52              
53             =head1 Experimental Features
54              
55             Some of the features of this module are currently marked as experimental. They
56             will provoke warnings in the C category, unless silenced.
57              
58             You can silence this with C but then that will
59             silence every experimental warning, which may hide others unintentionally. For
60             a more fine-grained approach you can instead use the import line for this
61             module to only silence this module's warnings selectively:
62              
63             use Syntax::Keyword::Try qw( try :experimental(typed) );
64              
65             use Syntax::Keyword::Try qw( try :experimental ); # all of the above
66              
67             Don't forget to import the main C symbol itself, to activate the syntax.
68              
69             =cut
70              
71             =head1 KEYWORDS
72              
73             =head2 try
74              
75             try {
76             STATEMENTS...
77             }
78             ...
79              
80             A C statement provides the main body of code that will be invoked, and
81             must be followed by either a C statement, a C statement, or
82             both.
83              
84             Execution of the C statement itself begins from the block given to the
85             statement and continues until either it throws an exception, or completes
86             successfully by reaching the end of the block. What will happen next depends
87             on the presence of a C or C statement immediately following
88             it.
89              
90             The body of a C block may contain a C expression. If executed,
91             such an expression will cause the entire containing function to return with
92             the value provided. This is different from a plain C block, in which
93             circumstance only the C itself would return, not the entire function.
94              
95             The body of a C block may contain loop control expressions (C,
96             C, C) which will have their usual effect on any loops that the
97             C block is contained by.
98              
99             The parsing rules for the set of statements (the C block and its
100             associated C and C) are such that they are parsed as a self-
101             contained statement. Because of this, there is no need to end with a
102             terminating semicolon.
103              
104             Even though it parses as a statement and not an expression, a C block can
105             still yield a value if it appears as the final statement in its containing
106             C or C block. For example:
107              
108             my $result = do {
109             try { attempt_func() }
110             catch ($e) { "Fallback Value" }
111             };
112              
113             Note (especially to users of L and similar) that the C
114             block itself does not necessarily stop exceptions thrown inside it from
115             propagating outside. It is the presence of a later C block which
116             causes this to happen. A C with only a C and no C will
117             still propagate exceptions up to callers as normal.
118              
119             =head2 catch
120              
121             ...
122             catch ($var) {
123             STATEMENTS...
124             }
125              
126             or
127              
128             ...
129             catch {
130             STATEMENTS...
131             }
132              
133             A C statement provides a block of code to the preceding C
134             statement that will be invoked in the case that the main block of code throws
135             an exception. Optionally a new lexical variable can be provided to store the
136             exception in. If not provided, the C block can inspect the raised
137             exception by looking in C<$@> instead.
138              
139             Presence of this C statement causes any exception thrown by the
140             preceding C block to be non-fatal to the surrounding code. If the
141             C block wishes to optionally handle some exceptions but not others, it
142             can re-raise it (or another exception) by calling C in the usual manner.
143              
144             As with C, the body of a C block may also contain a C
145             expression, which as before, has its usual meaning, causing the entire
146             containing function to return with the given value. The body may also contain
147             loop control expressions (C, C or C) which also have their
148             usual effect.
149              
150             If a C statement is not given, then any exceptions raised by the C
151             block are raised to the caller in the usual way.
152              
153             =head2 catch (Typed)
154              
155             ...
156             catch ($var isa Class) { ... }
157              
158             ...
159             catch ($var =~ m/^Regexp match/) { ... }
160              
161             I
162              
163             Optionally, multiple catch statements can be provided, where each block is
164             given a guarding condition, to control whether or not it will catch particular
165             exception values. Use of this syntax will provoke an C category
166             warning on supporting perl versions, unless silenced by importing the
167             C<:experimental(typed)> tag (see above).
168              
169             Two kinds of condition are supported:
170              
171             =over 4
172              
173             =item *
174              
175             catch ($var isa Class)
176              
177             The block is invoked only if the caught exception is a blessed object, and
178             derives from the given package name.
179              
180             On Perl version 5.32 onwards, this condition test is implemented using the
181             same op type that the core C<$var isa Class> syntax is provided by and works
182             in exactly the same way.
183              
184             On older perl versions it is emulated by a compatibility function. Currently
185             this function does not respect a C<< ->isa >> method overload on the exception
186             instance. Usually this should not be a problem, as exception class types
187             rarely provide such a method.
188              
189             =item *
190              
191             catch ($var =~ m/regexp/)
192              
193             The block is invoked only if the caught exception is a string that matches
194             the given regexp.
195              
196             =back
197              
198             When an exception is caught, each condition is tested in the order they are
199             written in, until a matching case is found. If such a case is found the
200             corresponding block is invoked, and no further condition is tested. If no
201             contional block matched and there is a default (unconditional) block at the
202             end then that is invoked instead. If no such block exists, then the exception
203             is propagated up to the calling scope.
204              
205             =head2 finally
206              
207             ...
208             finally {
209             STATEMENTS...
210             }
211              
212             A C statement provides a block of code to the preceding C
213             statement (or C pair) which is executed afterwards, both in the
214             case of a normal execution or a thrown exception. This code block may be used
215             to provide whatever clean-up operations might be required by preceding code.
216              
217             Because it is executed during a stack cleanup operation, a C block
218             may not cause the containing function to return, or to alter the return value
219             of it. It also cannot see the containing function's C<@_> arguments array
220             (though as it is block scoped within the function, it will continue to share
221             any normal lexical variables declared up until that point). It is protected
222             from disturbing the value of C<$@>. If the C block code throws an
223             exception, this will be printed as a warning and discarded, leaving C<$@>
224             containing the original exception, if one existed.
225              
226             =head1 OTHER MODULES
227              
228             There are already quite a number of modules on CPAN that provide a
229             C-like syntax for Perl.
230              
231             =over 2
232              
233             =item *
234              
235             L
236              
237             =item *
238              
239             L
240              
241             =item *
242              
243             L
244              
245             =item *
246              
247             L
248              
249             =back
250              
251             In addition, core perl itself gained a C syntax based on this
252             module at version 5.34.0. It is available as C.
253              
254             They are compared here, by feature:
255              
256             =head2 True syntax plugin
257              
258             Like L and L, this module is implemented as a true
259             syntax plugin, allowing it to provide new parsing rules not available to
260             simple functions. Most notably here it means that the resulting combination
261             does not need to end in a semicolon.
262              
263             The core C is also implemented as true native syntax in the
264             perl parser.
265              
266             In comparison, L is plain perl and provides its functionality using
267             regular perl functions; as such its syntax requires the trailing semicolon.
268              
269             L is a hybrid that uses L to parse the syntax tree.
270              
271             =head2 C<@_> in a try or catch block
272              
273             Because the C and C block code is contained in a true block rather
274             than an entire anonymous subroutine, invoking it does not interfere with the
275             C<@_> arguments array. Code inside these blocks can interact with the
276             containing function's array as before.
277              
278             This feature is unique among these modules; none of the others listed have
279             this ability.
280              
281             The core C also behaves in this manner.
282              
283             =head2 C in a try or catch block
284              
285             Like L and L, the C statement has its
286             usual effect within a subroutine containing syntax provided by this module.
287             Namely, it causes the containing C itself to return.
288              
289             It also behaves this way using the core C.
290              
291             In comparison, using L or L mean that a C statement
292             will only exit from the C block.
293              
294             =head2 C/C/C in a try or catch block
295              
296             The loop control keywords of C, C and C have their usual
297             effect on dynamically contained loops.
298              
299             These also work fine when using the core C.
300              
301             L documents that these do not work there. The other
302             modules make no statement either way.
303              
304             =head2 Value Semantics
305              
306             Like L and L, the syntax provided by this module
307             only works as a syntax-level statement and not an expression. You cannot
308             assign from the result of a C block. A common workaround is to wrap
309             the C statement inside a C block, where its final expression
310             can be captured and used as a value.
311              
312             The same C block wrapping also works for the core C.
313              
314             In comparison, the behaviour implemented by L can be used as a
315             valued expression, such as assigned to a variable or returned to the caller of
316             its containing function.
317              
318             =head2 C without C
319              
320             Like L, the syntax provided by this module allows a
321             C block to be followed by only a C block, with no C. In
322             this case, exceptions thrown by code contained by the C are not
323             suppressed, instead they propagate as normal to callers. This matches the
324             behaviour familiar to Java or C++ programmers.
325              
326             In comparison, the code provided by L and L always suppress
327             exception propagation even without an actual C block.
328              
329             The L module does not allow a C block not followed by C.
330              
331             The core C does not implement C at all, and also
332             requires that every C block be followed by a C.
333              
334             =head2 Typed C
335              
336             L and L make no attempt to perform any kind of typed dispatch
337             to distinguish kinds of exception caught by C blocks.
338              
339             Likewise the core C currently does not provide this ability,
340             though it remains an area of ongoing design work.
341              
342             L and L both attempt to provide a kind of
343             typed dispatch where different classes of exception are caught by different
344             blocks of code, or propagated up entirely to callers.
345              
346             This module provides such an ability, via the currently-experimental
347             C syntax.
348              
349             The design thoughts continue on the RT ticket
350             L.
351              
352             =cut
353              
354             sub import
355             {
356 17     17   130 my $class = shift;
357 17         40 my $caller = caller;
358              
359 17         55 $class->import_into( $caller, @_ );
360             }
361              
362             my @EXPERIMENTAL = qw( typed );
363              
364             sub import_into
365             {
366 17     17 0 32 my $class = shift;
367 17         36 my ( $caller, @syms ) = @_;
368              
369 17 100       77 @syms or @syms = qw( try );
370              
371 17         43 my %syms = map { $_ => 1 } @syms;
  18         75  
372 17 100       140 $^H{"Syntax::Keyword::Try/try"}++ if delete $syms{try};
373              
374             # Largely for Feature::Compat::Try's benefit
375 17 100       63 $^H{"Syntax::Keyword::Try/no_finally"}++ if delete $syms{"-no_finally"};
376 17 50       48 $^H{"Syntax::Keyword::Try/require_catch"}++ if delete $syms{"-require_catch"};
377 17 100       73 $^H{"Syntax::Keyword::Try/require_var"}++ if delete $syms{"-require_var"};
378              
379             # stablised experiments
380 17         98 delete $syms{":experimental($_)"} for qw( var );
381              
382 17         77 foreach ( @EXPERIMENTAL ) {
383 17 50       153 $^H{"Syntax::Keyword::Try/experimental($_)"}++ if delete $syms{":experimental($_)"};
384             }
385              
386 17 100       76 if( delete $syms{":experimental"} ) {
387 2         14 $^H{"Syntax::Keyword::Try/experimental($_)"}++ for @EXPERIMENTAL;
388             }
389              
390             # Ignore requests for these, as they come automatically with `try`
391 17         77 delete @syms{qw( catch finally )};
392              
393 16 50 33     113 if( $syms{try_value} or $syms{":experimental(try_value)"} ) {
394 0         0 croak "The 'try_value' experimental feature is now removed\n" .
395             "Instead, you should use do { try ... } to yield a value from a try/catch statement";
396             }
397              
398 16 50       19533 croak "Unrecognised import symbols @{[ keys %syms ]}" if keys %syms;
  0            
399             }
400              
401             =head1 WITH OTHER MODULES
402              
403             =head2 Future::AsyncAwait
404              
405             As of C version 0.10 and L version
406             0.07, cross-module integration tests assert that basic C blocks
407             inside an C work correctly, including those that attempt to
408             C from inside C.
409              
410             use Future::AsyncAwait;
411             use Syntax::Keyword::Try;
412              
413             async sub attempt
414             {
415             try {
416             await func();
417             return "success";
418             }
419             catch {
420             return "failed";
421             }
422             }
423              
424             =head1 ISSUES
425              
426             =head2 Thread-safety at load time cannot be assured before perl 5.16
427              
428             On F versions 5.16 and above this module is thread-safe.
429              
430             On F version 5.14 this module is thread-safe provided that it is
431             Cd before any additional threads are created.
432              
433             However, when using 5.14 there is a race condition if this module is loaded
434             late in the program startup, after additional threads have been created. This
435             leads to the potential for it to be started up multiple times concurrently,
436             which creates data races when modifying internal structures and likely leads
437             to a segmentation fault, either during load or soon after when more code is
438             compiled.
439              
440             As a workaround, for any such program that creates multiple threads, loads
441             additional code (such as dynamically-discovered plugins), and has to run on
442             5.14, it should make sure to
443              
444             use Syntax::Keyword::Try;
445              
446             early on in startup, before it spins out any additional threads.
447              
448             (See also L)
449              
450             =head2 $@ is not local'ised by C before perl 5.24
451              
452             On F versions 5.24 and above, or when using only control-flow statement
453             syntax, C<$@> is always correctly Cised.
454              
455             However, when using the experimental value-yielding expression version
456             C on perl versions 5.22 or older, the Cisation of C<$@>
457             does not correctly apply around the expression. After such an expression, the
458             value of C<$@> will leak out if a failure happened and the C block was
459             invoked, overwriting any previous value that was visible there.
460              
461             (See also L)
462              
463             =head1 ACKNOWLEDGEMENTS
464              
465             With thanks to C, C and others from C for
466             assisting with trickier bits of XS logic.
467              
468             =head1 AUTHOR
469              
470             Paul Evans
471              
472             =cut
473              
474             0x55AA;