← Index
NYTProf Performance Profile   « line view »
For ../prof.pl
  Run on Wed Dec 14 16:10:05 2022
Reported on Wed Dec 14 16:12:56 2022

Filename/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Feature/Compat/Try.pm
StatementsExecuted 33 statements in 809µs
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1112.13ms2.69msFeature::Compat::Try::::BEGIN@13Feature::Compat::Try::BEGIN@13
66640µs192µsFeature::Compat::Try::::importFeature::Compat::Try::import
11133µs33µsFeature::Compat::Try::::BEGIN@8Feature::Compat::Try::BEGIN@8
11110µs65µsFeature::Compat::Try::::BEGIN@9Feature::Compat::Try::BEGIN@9
1116µs6µsFeature::Compat::Try::::BEGIN@10Feature::Compat::Try::BEGIN@10
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
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, 2021-2022 -- leonerd@leonerd.org.uk
5
6package Feature::Compat::Try 0.05;
7
8251µs133µs
# spent 33µs within Feature::Compat::Try::BEGIN@8 which was called: # once (33µs+0s) by OpenAPI::Modern::BEGIN@23 at line 8
use v5.14;
# spent 33µs making 1 call to Feature::Compat::Try::BEGIN@8
9245µs2120µs
# spent 65µs (10+55) within Feature::Compat::Try::BEGIN@9 which was called: # once (10µs+55µs) by OpenAPI::Modern::BEGIN@23 at line 9
use warnings;
# spent 65µs making 1 call to Feature::Compat::Try::BEGIN@9 # spent 55µs making 1 call to warnings::import
10240µs16µs
# spent 6µs within Feature::Compat::Try::BEGIN@10 which was called: # once (6µs+0s) by OpenAPI::Modern::BEGIN@23 at line 10
use feature ();
# spent 6µs making 1 call to Feature::Compat::Try::BEGIN@10
11
12# Core's use feature 'try' only supports 'finally' since 5.35.8
132622µs22.83ms
# spent 2.69ms (2.13+560µs) within Feature::Compat::Try::BEGIN@13 which was called: # once (2.13ms+560µs) by OpenAPI::Modern::BEGIN@23 at line 13
use constant HAVE_FEATURE_TRY => $] >= 5.035008;
# spent 2.69ms making 1 call to Feature::Compat::Try::BEGIN@13 # spent 144µs making 1 call to constant::import
14
15=head1 NAME
16
17C<Feature::Compat::Try> - make C<try/catch> syntax available
18
19=head1 SYNOPSIS
20
21 use Feature::Compat::Try;
22
23 sub foo
24 {
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
37This module makes syntax support for C<try/catch> control flow easily
38available.
39
40Perl added such syntax at version 5.34.0, and extended it to support optional
41C<finally> blocks at 5.35.9, which is enabled by
42
43 use feature 'try';
44
45On that version of perl or later, this module simply enables the core feature
46equivalent to using it directly. On such perls, this module will install with
47no non-core dependencies, and requires no C compiler.
48
49On older versions of perl before such syntax is available, it is currently
50provided instead using the L<Syntax::Keyword::Try> module, imported with a
51special set of options to configure it to recognise exactly and only the same
52syntax as the core perl feature, thus ensuring that any code using it will
53still continue to function on that newer perl.
54
55=cut
56
57=head1 KEYWORDS
58
59=head2 try
60
61 try {
62 STATEMENTS...
63 }
64 ...
65
66A C<try> statement provides the main body of code that will be invoked, and
67must be followed by a C<catch> statement. It may optionally be followed by
68a C<finally> statement.
69
70Execution of the C<try> statement itself begins from the block given to the
71statement and continues until either it throws an exception, or completes
72successfully by reaching the end of the block.
73
74The body of a C<try {}> block may contain a C<return> expression. If executed,
75such an expression will cause the entire containing function to return with
76the value provided. This is different from a plain C<eval {}> block, in which
77circumstance only the C<eval> itself would return, not the entire function.
78
79The body of a C<try {}> block may contain loop control expressions (C<redo>,
80C<next>, C<last>) which will have their usual effect on any loops that the
81C<try {}> block is contained by.
82
83The parsing rules for the set of statements (the C<try> block and its
84associated C<catch>) are such that they are parsed as a self-contained
85statement. Because of this, there is no need to end with a terminating
86semicolon.
87
88Even though it parses as a statement and not an expression, a C<try> block can
89still yield a value if it appears as the final statement in its containing
90C<sub> or C<do> block. For example:
91
92 my $result = do {
93 try { attempt_func() }
94 catch ($e) { "Fallback Value" }
95 };
96
97=head2 catch
98
99 ...
100 catch ($var) {
101 STATEMENTS...
102 }
103
104A C<catch> statement provides a block of code to the preceding C<try>
105statement that will be invoked in the case that the main block of code throws
106an exception. A new lexical variable is created to store the exception in.
107
108Presence of this C<catch> statement causes any exception thrown by the
109preceding C<try> block to be non-fatal to the surrounding code. If the
110C<catch> block wishes to optionally handle some exceptions but not others, it
111can re-raise it (or another exception) by calling C<die> in the usual manner.
112
113As with C<try>, the body of a C<catch {}> block may also contain a C<return>
114expression, which as before, has its usual meaning, causing the entire
115containing function to return with the given value. The body may also contain
116loop control expressions (C<redo>, C<next> or C<last>) which also have their
117usual effect.
118
119=head2 finally
120
121 ...
122 finally {
123 STATEMENTS...
124 }
125
126A C<finally> statement provides an optional block of code to the preceding
127C<try>/C<catch> pair which is executed afterwards, both in the case of a
128normal execution or a thrown exception. This code block may be used to
129provide whatever clean-up operations might be required by preceding code.
130
131Because it is executed during a stack cleanup operation, a C<finally {}> block
132may not cause the containing function to return, or to alter the return value
133of it. It also cannot see the containing function's C<@_> arguments array
134(though as it is block scoped within the function, it will continue to share
135any normal lexical variables declared up until that point). It is protected
136from disturbing the value of C<$@>. If the C<finally {}> block code throws an
137exception, this will be printed as a warning and discarded, leaving C<$@>
138containing the original exception, if one existed.
139=cut
140
141sub import
142
# spent 192µs (40+152) within Feature::Compat::Try::import which was called 6 times, avg 32µs/call: # once (9µs+57µs) by OpenAPI::Modern::BEGIN@23 at line 23 of OpenAPI/Modern.pm # once (13µs+46µs) by JSON::Schema::Modern::BEGIN@32 at line 32 of JSON/Schema/Modern.pm # once (6µs+14µs) by JSON::Schema::Modern::Vocabulary::FormatAssertion::BEGIN@18 at line 18 of JSON/Schema/Modern/Vocabulary/FormatAssertion.pm # once (4µs+13µs) by JSON::Schema::Modern::Vocabulary::FormatAnnotation::BEGIN@18 at line 18 of JSON/Schema/Modern/Vocabulary/FormatAnnotation.pm # once (4µs+12µs) by JSON::Schema::Modern::Utilities::BEGIN@22 at line 22 of JSON/Schema/Modern/Utilities.pm # once (4µs+10µs) by JSON::Schema::Modern::Vocabulary::Content::BEGIN@18 at line 18 of JSON/Schema/Modern/Vocabulary/Content.pm
{
143625µs if( HAVE_FEATURE_TRY ) {
144610µs671µs feature->import(qw( try ));
# spent 71µs making 6 calls to feature::import, avg 12µs/call
14562µs require warnings;
146610µs681µs warnings->unimport(qw( experimental::try ));
# spent 81µs making 6 calls to warnings::unimport, avg 14µs/call
147 }
148 else {
149 require Syntax::Keyword::Try;
150 Syntax::Keyword::Try->VERSION( '0.27' );
151 Syntax::Keyword::Try->import(qw( try -require_catch -require_var ));
152 }
153}
154
155=head1 COMPATIBILITY NOTES
156
157This module may use either L<Syntax::Keyword::Try> or the perl core C<try>
158feature to implement its syntax. While the two behave very similarly, and both
159conform to the description given above, the following differences should be
160noted.
161
162=over 4
163
164=item * Visibility to C<caller()>
165
166The C<Syntax::Keyword::Try> module implements C<try> blocks by using C<eval>
167frames. As a result, they are visible to the C<caller()> function and hence to
168things like C<Carp::longmess> when viewed as stack traces.
169
170By comparison, core's C<feature 'try'> creates a new kind of context stack
171entry that is ignored by C<caller()> and hence these blocks do not show up in
172stack traces.
173
174This should not matter to most use-cases - e.g. even C<Carp::croak> will be
175fine here. But if you are using C<caller()> with calculated indexes to inspect
176the state of callers to your code and there may be C<try> frames in the way,
177you will need to somehow account for the difference in stack height.
178
179=item * C<B::Deparse>
180
181The core C<feature 'try'> is implemented by emitting real opcodes that
182represent its behaviour, which is recognised by the version of L<B::Deparse>
183that ships with core perl. As a result, any code using this implementation
184will deparse currently with tools like C<perl -MO=Deparse ...>, or others
185related to it such as coverage checkers.
186
187By comparison, since C<Syntax::Keyword::Try> uses C<OP_CUSTOM> it is not
188recognised by C<B::Deparse> and so attempts to deparse this will result in
189error messages like
190
191 unexpected OP_CUSTOM (catch) at ...
192
193This is rather unavoidable due to the way that C<B::Deparse> is implemented
194and does not easily support custom operators.
195
196See also L<https://rt.cpan.org/Ticket/Display.html?id=134812>.
197
198=back
199
200=cut
201
202=head1 AUTHOR
203
204Paul Evans <leonerd@leonerd.org.uk>
205
206=cut
207
20814µs0x55AA;