1Syntax::Keyword::Try(3)User Contributed Perl DocumentatioSnyntax::Keyword::Try(3)
2
3
4

NAME

6       "Syntax::Keyword::Try" - a "try/catch/finally" syntax for perl
7

SYNOPSIS

9          use Syntax::Keyword::Try;
10
11          sub foo {
12             try {
13                attempt_a_thing();
14                return "success";
15             }
16             catch ($e) {
17                warn "It failed - $e";
18                return "failure";
19             }
20          }
21

DESCRIPTION

23       This module provides a syntax plugin that implements exception-handling
24       semantics in a form familiar to users of other languages, being built
25       on a block labeled with the "try" keyword, followed by at least one of
26       a "catch" or "finally" block.
27
28       As well as providing a handy syntax for this useful behaviour, this
29       module also serves to contain a number of code examples for how to
30       implement parser plugins and manipulate optrees to provide new syntax
31       and behaviours for perl code.
32

Experimental Features

34       Some of the features of this module are currently marked as
35       experimental. They will provoke warnings in the "experimental"
36       category, unless silenced.
37
38       You can silence this with "no warnings 'experimental'" but then that
39       will silence every experimental warning, which may hide others
40       unintentionally. For a more fine-grained approach you can instead use
41       the import line for this module to only silence this module's warnings
42       selectively:
43
44          use Syntax::Keyword::Try qw( try :experimental(typed) );
45
46          use Syntax::Keyword::Try qw( try :experimental(try_value) );
47
48          use Syntax::Keyword::Try qw( try :experimental );  # all of the above
49
50       Don't forget to import the main "try" symbol itself, to activate the
51       syntax.
52

KEYWORDS

54   try
55          try {
56             STATEMENTS...
57          }
58          ...
59
60       A "try" statement provides the main body of code that will be invoked,
61       and must be followed by either a "catch" statement, a "finally"
62       statement, or both.
63
64       Execution of the "try" statement itself begins from the block given to
65       the statement and continues until either it throws an exception, or
66       completes successfully by reaching the end of the block. What will
67       happen next depends on the presence of a "catch" or "finally" statement
68       immediately following it.
69
70       The body of a "try {}" block may contain a "return" expression. If
71       executed, such an expression will cause the entire containing function
72       to return with the value provided. This is different from a plain "eval
73       {}" block, in which circumstance only the "eval" itself would return,
74       not the entire function.
75
76       The body of a "try {}" block may contain loop control expressions
77       ("redo", "next", "last") which will have their usual effect on any
78       loops that the "try {}" block is contained by.
79
80       The parsing rules for the set of statements (the "try" block and its
81       associated "catch" and "finally") are such that they are parsed as a
82       self- contained statement. Because of this, there is no need to end
83       with a terminating semicolon.
84
85       Even though it parses as a statement and not an expression, a "try"
86       block can still yield a value if it appears as the final statement in
87       its containing "sub" or "do" block. For example:
88
89          my $result = do {
90             try { attempt_func() }
91             catch ($e) { "Fallback Value" }
92          };
93
94       Note (especially to users of Try::Tiny and similar) that the "try {}"
95       block itself does not necessarily stop exceptions thrown inside it from
96       propagating outside. It is the presence of a later "catch {}" block
97       which causes this to happen. A "try" with only a "finally" and no
98       "catch" will still propagate exceptions up to callers as normal.
99
100   catch
101          ...
102          catch ($var) {
103             STATEMENTS...
104          }
105
106       or
107
108          ...
109          catch {
110             STATEMENTS...
111          }
112
113       A "catch" statement provides a block of code to the preceding "try"
114       statement that will be invoked in the case that the main block of code
115       throws an exception. Optionally a new lexical variable can be provided
116       to store the exception in. If not provided, the "catch" block can
117       inspect the raised exception by looking in $@ instead.
118
119       Presence of this "catch" statement causes any exception thrown by the
120       preceding "try" block to be non-fatal to the surrounding code. If the
121       "catch" block wishes to optionally handle some exceptions but not
122       others, it can re-raise it (or another exception) by calling "die" in
123       the usual manner.
124
125       As with "try", the body of a "catch {}" block may also contain a
126       "return" expression, which as before, has its usual meaning, causing
127       the entire containing function to return with the given value. The body
128       may also contain loop control expressions ("redo", "next" or "last")
129       which also have their usual effect.
130
131       If a "catch" statement is not given, then any exceptions raised by the
132       "try" block are raised to the caller in the usual way.
133
134   catch (Typed)
135          ...
136          catch ($var isa Class) { ... }
137
138          ...
139          catch ($var =~ m/^Regexp match/) { ... }
140
141       Experimental; since version 0.15.
142
143       Optionally, multiple catch statements can be provided, where each block
144       is given a guarding condition, to control whether or not it will catch
145       particular exception values. Use of this syntax will provoke an
146       "experimental" category warning on supporting perl versions, unless
147       silenced by importing the ":experimental(typed)" tag (see above).
148
149       Two kinds of condition are supported:
150
151
152
153
154              catch ($var isa Class)
155
156           The block is invoked only if the caught exception is a blessed
157           object, and derives from the given package name.
158
159           On Perl version 5.32 onwards, this condition test is implemented
160           using the same op type that the core "$var isa Class" syntax is
161           provided by and works in exactly the same way.
162
163           On older perl versions it is emulated by a compatibility function.
164           Currently this function does not respect a "->isa" method overload
165           on the exception instance. Usually this should not be a problem, as
166           exception class types rarely provide such a method.
167
168
169
170
171              catch ($var =~ m/regexp/)
172
173           The block is invoked only if the caught exception is a string that
174           matches the given regexp.
175
176       When an exception is caught, each condition is tested in the order they
177       are written in, until a matching case is found. If such a case is found
178       the corresponding block is invoked, and no further condition is tested.
179       If no contional block matched and there is a default (unconditional)
180       block at the end then that is invoked instead. If no such block exists,
181       then the exception is propagated up to the calling scope.
182
183   finally
184          ...
185          finally {
186             STATEMENTS...
187          }
188
189       A "finally" statement provides a block of code to the preceding "try"
190       statement (or "try/catch" pair) which is executed afterwards, both in
191       the case of a normal execution or a thrown exception. This code block
192       may be used to provide whatever clean-up operations might be required
193       by preceding code.
194
195       Because it is executed during a stack cleanup operation, a "finally {}"
196       block may not cause the containing function to return, or to alter the
197       return value of it. It also cannot see the containing function's @_
198       arguments array (though as it is block scoped within the function, it
199       will continue to share any normal lexical variables declared up until
200       that point). It is protected from disturbing the value of $@. If the
201       "finally {}" block code throws an exception, this will be printed as a
202       warning and discarded, leaving $@ containing the original exception, if
203       one existed.
204

VALUE SEMANTICS

206           Warning: the feature described in this section is experimental.
207           This experiment has existed for a while, though given that since
208           version 0.22 the regular "try" syntax already behaves fine inside a
209           "do" block, there is no longer any reason for this experimental
210           feature to exist. It will start printing deprecation warnings in a
211           later version, and eventually will be removed.
212
213           Additionally, on perl versions 5.18 and later, it will produce a
214           warning in the "experimental" category.
215
216       The syntax provided by this module may be used as a value-yielding
217       expression.  Because this syntax is new, experimental, and somewhat
218       surprising, it must be specifically requested by name "try_value":
219
220          use Syntax::Keyword::Try qw( try try_value );
221
222          my $result = try do { ... } catch { ... };
223
224       Also, on Perl versions 5.24 and later:
225
226          my $result = try do { ... } finally { ... };
227
228          my $result = try do { ... } catch { ... } finally { ... };
229
230       Specifically, note that the expression must be spelled as "try do { ...
231       }" so that the syntax is distinct from that used by control-flow
232       statements. The interposed "do" keyword reminds the reader, and
233       instructs the syntax parser, that this will be an expression, not a
234       statement. It is not necessary to similarly notate the "catch" or
235       "finally" blocks.
236
237       In this case, the syntax behaves syntactically like an expression, and
238       may appear anywhere a normal expression is allowed. It follows similar
239       semantics to the purely control-flow case; if the code in the "try"
240       block does not throw an exception, then the expression as a whole
241       yields whatever value the "try" expression did. If it fails, then the
242       "catch" block is executed and the expression yields its resulting value
243       instead. A "finally" block, if present, will be evaluated for side-
244       effects before the rest of the expression returns.
245
246       Remember that, as in the control-flow case, the "return" keyword will
247       cause the entire containing function to return, not just the "try"
248       block.
249

OTHER MODULES

251       There are already quite a number of modules on CPAN that provide a
252       "try/catch"-like syntax for Perl.
253
254       • Try
255
256       • TryCatch
257
258       • Try::Tiny
259
260       • Syntax::Feature::Try
261
262       In addition, core perl itself gained a "try/catch" syntax based on this
263       module at developemnt version 5.33.7, and should become generally
264       available when 5.34 is released. It will be available as "use feature
265       'try'".
266
267       They are compared here, by feature:
268
269   True syntax plugin
270       Like Try and Syntax::Feature::Try, this module is implemented as a true
271       syntax plugin, allowing it to provide new parsing rules not available
272       to simple functions. Most notably here it means that the resulting
273       combination does not need to end in a semicolon.
274
275       The core "feature 'try'" is also implemented as true native syntax in
276       the perl parser.
277
278       In comparison, Try::Tiny is plain perl and provides its functionality
279       using regular perl functions; as such its syntax requires the trailing
280       semicolon.
281
282       TryCatch is a hybrid that uses Devel::Declare to parse the syntax tree.
283
284   @_ in a try or catch block
285       Because the "try" and "catch" block code is contained in a true block
286       rather than an entire anonymous subroutine, invoking it does not
287       interfere with the @_ arguments array. Code inside these blocks can
288       interact with the containing function's array as before.
289
290       This feature is unique among these modules; none of the others listed
291       have this ability.
292
293       The core "feature 'try'" also behaves in this manner.
294
295   "return" in a try or catch block
296       Like TryCatch and Syntax::Feature::Try, the "return" statement has its
297       usual effect within a subroutine containing syntax provided by this
298       module.  Namely, it causes the containing "sub" itself to return.
299
300       It also behaves this way using the core "feature 'try'".
301
302       In comparison, using Try or Try::Tiny mean that a "return" statement
303       will only exit from the "try" block.
304
305   "next"/"last"/"redo" in a try or catch block
306       The loop control keywords of "next", "last" and "redo" have their usual
307       effect on dynamically contained loops.
308
309       These also work fine when using the core "feature 'try'".
310
311       Syntax::Feature::Try documents that these do not work there. The other
312       modules make no statement either way.
313
314   Value Semantics
315       Like Try and Syntax::Feature::Try, the syntax provided by this module
316       only works as a syntax-level statement and not an expression when the
317       experimental "try_value" feature described above has not been enabled.
318       You cannot assign from the result of a "try" block. A common workaround
319       is to wrap the "try/catch" statement inside a "do" block, where its
320       final expression can be captured and used as a value.
321
322       The same "do" block wrapping also works for the core "feature 'try'".
323
324       In comparison, the behaviour implemented by Try::Tiny can be used as a
325       valued expression, such as assigned to a variable or returned to the
326       caller of its containing function.
327
328   "try" without "catch"
329       Like Syntax::Feature::Try, the syntax provided by this module allows a
330       "try" block to be followed by only a "finally" block, with no "catch".
331       In this case, exceptions thrown by code contained by the "try" are not
332       suppressed, instead they propagate as normal to callers. This matches
333       the behaviour familiar to Java or C++ programmers.
334
335       In comparison, the code provided by Try and Try::Tiny always suppress
336       exception propagation even without an actual "catch" block.
337
338       The TryCatch module does not allow a "try" block not followed by
339       "catch".
340
341       The core "feature 'try'" does not implement "finally" at all, and also
342       requires that every "try" block be followed by a "catch".
343
344   Typed "catch"
345       Try and Try::Tiny make no attempt to perform any kind of typed dispatch
346       to distinguish kinds of exception caught by "catch" blocks.
347
348       Likewise the core "feature 'try'" currently does not provide this
349       ability, though it remains an area of ongoing design work.
350
351       TryCatch and Syntax::Feature::Try both attempt to provide a kind of
352       typed dispatch where different classes of exception are caught by
353       different blocks of code, or propagated up entirely to callers.
354
355       This module provides such an ability, via the currently-experimental
356       "catch (VAR cond...)" syntax.
357
358       The design thoughts continue on the RT ticket
359       <https://rt.cpan.org/Ticket/Display.html?id=123918>.
360

WITH OTHER MODULES

362   Future::AsyncAwait
363       As of "Future::AsyncAwait" version 0.10 and Syntax::Keyword::Try
364       version 0.07, cross-module integration tests assert that basic
365       "try/catch" blocks inside an "async sub" work correctly, including
366       those that attempt to "return" from inside "try".
367
368          use Future::AsyncAwait;
369          use Syntax::Keyword::Try;
370
371          async sub attempt
372          {
373             try {
374                await func();
375                return "success";
376             }
377             catch {
378                return "failed";
379             }
380          }
381

ISSUES

383   Thread-safety at load time cannot be assured before perl 5.16
384       On perl versions 5.16 and above this module is thread-safe.
385
386       On perl version 5.14 this module is thread-safe provided that it is
387       "use"d before any additional threads are created.
388
389       However, when using 5.14 there is a race condition if this module is
390       loaded late in the program startup, after additional threads have been
391       created. This leads to the potential for it to be started up multiple
392       times concurrently, which creates data races when modifying internal
393       structures and likely leads to a segmentation fault, either during load
394       or soon after when more code is compiled.
395
396       As a workaround, for any such program that creates multiple threads,
397       loads additional code (such as dynamically-discovered plugins), and has
398       to run on 5.14, it should make sure to
399
400          use Syntax::Keyword::Try;
401
402       early on in startup, before it spins out any additional threads.
403
404       (See also <https://rt.cpan.org/Public/Bug/Display.html?id=123547>)
405
406   $@ is not local'ised by "try do" before perl 5.24
407       On perl versions 5.24 and above, or when using only control-flow
408       statement syntax, $@ is always correctly "local"ised.
409
410       However, when using the experimental value-yielding expression version
411       "try do {...}" on perl versions 5.22 or older, the "local"isation of $@
412       does not correctly apply around the expression. After such an
413       expression, the value of $@ will leak out if a failure happened and the
414       "catch" block was invoked, overwriting any previous value that was
415       visible there.
416
417       (See also <https://rt.cpan.org/Public/Bug/Display.html?id=124366>)
418

ACKNOWLEDGEMENTS

420       With thanks to "Zefram", "ilmari" and others from "irc.perl.org/#p5p"
421       for assisting with trickier bits of XS logic.
422

AUTHOR

424       Paul Evans <leonerd@leonerd.org.uk>
425
426
427
428perl v5.32.1                      2021-03-29           Syntax::Keyword::Try(3)
Impressum