← Index
NYTProf Performance Profile   « line view »
For ../prof.pl
  Run on Wed Dec 14 15:33:55 2022
Reported on Wed Dec 14 15:40:03 2022

Filename/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Try/Tiny.pm
StatementsExecuted 72 statements in 746µs
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
21146µs8.91msTry::Tiny::::try Try::Tiny::try
11122µs22µsTry::Tiny::::BEGIN@2 Try::Tiny::BEGIN@2
21119µs34µsTry::Tiny::::catch Try::Tiny::catch
11111µs21µsTry::Tiny::::BEGIN@10 Try::Tiny::BEGIN@10
1119µs25µsTry::Tiny::::BEGIN@8 Try::Tiny::BEGIN@8
1119µs49µsTry::Tiny::ScopeGuard::::BEGIN@167Try::Tiny::ScopeGuard::BEGIN@167
1117µs8µsTry::Tiny::::BEGIN@7 Try::Tiny::BEGIN@7
1114µs33µsTry::Tiny::::BEGIN@13 Try::Tiny::BEGIN@13
1114µs4µsTry::Tiny::::BEGIN@16 Try::Tiny::BEGIN@16
0000s0sTry::Tiny::ScopeGuard::::DESTROYTry::Tiny::ScopeGuard::DESTROY
0000s0sTry::Tiny::ScopeGuard::::_newTry::Tiny::ScopeGuard::_new
0000s0sTry::Tiny::::__ANON__[:28] Try::Tiny::__ANON__[:28]
0000s0sTry::Tiny::::finally Try::Tiny::finally
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Try::Tiny; # git description: v0.30-11-g1b81d0a
2242µs122µs
# spent 22µs within Try::Tiny::BEGIN@2 which was called: # once (22µs+0s) by Module::Implementation::BEGIN@9 at line 2
use 5.006;
# spent 22µs making 1 call to Try::Tiny::BEGIN@2
3# ABSTRACT: Minimal try/catch with proper preservation of $@
4
510sour $VERSION = '0.31';
6
7218µs29µs
# spent 8µs (7+1000ns) within Try::Tiny::BEGIN@7 which was called: # once (7µs+1000ns) by Module::Implementation::BEGIN@9 at line 7
use strict;
# spent 8µs making 1 call to Try::Tiny::BEGIN@7 # spent 1µs making 1 call to strict::import
8217µs241µs
# spent 25µs (9+16) within Try::Tiny::BEGIN@8 which was called: # once (9µs+16µs) by Module::Implementation::BEGIN@9 at line 8
use warnings;
# spent 25µs making 1 call to Try::Tiny::BEGIN@8 # spent 16µs making 1 call to warnings::import
9
10343µs331µs
# spent 21µs (11+10) within Try::Tiny::BEGIN@10 which was called: # once (11µs+10µs) by Module::Implementation::BEGIN@9 at line 10
use Exporter 5.57 'import';
# spent 21µs making 1 call to Try::Tiny::BEGIN@10 # spent 6µs making 1 call to Exporter::import # spent 4µs making 1 call to UNIVERSAL::VERSION
1112µsour @EXPORT = our @EXPORT_OK = qw(try catch finally);
12
132113µs262µs
# spent 33µs (4+29) within Try::Tiny::BEGIN@13 which was called: # once (4µs+29µs) by Module::Implementation::BEGIN@9 at line 13
use Carp;
# spent 33µs making 1 call to Try::Tiny::BEGIN@13 # spent 29µs making 1 call to Exporter::import
1411µs$Carp::Internal{+__PACKAGE__}++;
15
16
# spent 4µs within Try::Tiny::BEGIN@16 which was called: # once (4µs+0s) by Module::Implementation::BEGIN@9 at line 30
BEGIN {
1711µs my $su = $INC{'Sub/Util.pm'} && defined &Sub::Util::set_subname;
1811µs my $sn = $INC{'Sub/Name.pm'} && eval { Sub::Name->VERSION(0.08) };
1910s unless ($su || $sn) {
20 $su = eval { require Sub::Util; } && defined &Sub::Util::set_subname;
21 unless ($su) {
22 $sn = eval { require Sub::Name; Sub::Name->VERSION(0.08) };
23 }
24 }
25
26 *_subname = $su ? \&Sub::Util::set_subname
27 : $sn ? \&Sub::Name::subname
2810s : sub { $_[1] };
2915µs *_HAS_SUBNAME = ($su || $sn) ? sub(){1} : sub(){0};
301271µs14µs}
# spent 4µs making 1 call to Try::Tiny::BEGIN@16
31
3210smy %_finally_guards;
33
34# Need to prototype as @ not $$ because of the way Perl evaluates the prototype.
35# Keeping it at $$ means you only ever get 1 sub because we need to eval in a list
36# context & not a scalar one
37
38
# spent 8.91ms (46µs+8.87) within Try::Tiny::try which was called 2 times, avg 4.46ms/call: # 2 times (46µs+8.87ms) by Module::Implementation::_load_implementation at line 98 of Module/Implementation.pm, avg 4.46ms/call
sub try (&;@) {
3923µs my ( $try, @code_refs ) = @_;
40
41 # we need to save this here, the eval block will be in scalar context due
42 # to $failed
4320s my $wantarray = wantarray;
44
45 # work around perl bug by explicitly initializing these, due to the likelyhood
46 # this will be used in global destruction (perl rt#119311)
4722µs my ( $catch, @finally ) = ();
48
49 # find labeled blocks in the argument list.
50 # catch and finally tag the blocks by blessing a scalar reference to them.
5121µs foreach my $code_ref (@code_refs) {
52
5324µs if ( ref($code_ref) eq 'Try::Tiny::Catch' ) {
5422µs croak 'A try() may not be followed by multiple catch() blocks'
55 if $catch;
5622µs $catch = ${$code_ref};
57 } elsif ( ref($code_ref) eq 'Try::Tiny::Finally' ) {
58 push @finally, ${$code_ref};
59 } else {
60 croak(
61 'try() encountered an unexpected argument ('
62 . ( defined $code_ref ? $code_ref : 'undef' )
63 . ') - perhaps a missing semi-colon before or'
64 );
65 }
66 }
67
68 # FIXME consider using local $SIG{__DIE__} to accumulate all errors. It's
69 # not perfect, but we could provide a list of additional errors for
70 # $catch->();
71
72 # name the blocks if we have Sub::Name installed
73212µs26µs _subname(caller().'::try {...} ' => $try)
# spent 6µs making 2 calls to Sub::Util::set_subname, avg 3µs/call
74 if _HAS_SUBNAME;
75
76 # set up scope guards to invoke the finally blocks at the end.
77 # this should really be a function scope lexical variable instead of
78 # file scope + local but that causes issues with perls < 5.20 due to
79 # perl rt#119311
80 local $_finally_guards{guards} = [
8123µs map Try::Tiny::ScopeGuard->_new($_),
82 @finally
83 ];
84
85 # save the value of $@ so we can set $@ back to it in the beginning of the eval
86 # and restore $@ after the eval finishes
8721µs my $prev_error = $@;
88
8921µs my ( @ret, $error );
90
91 # failed will be true if the eval dies, because 1 will not be returned
92 # from the eval body
9321µs my $failed = not eval {
9421µs $@ = $prev_error;
95
96 # evaluate the try block in the correct context
9722µs if ( $wantarray ) {
98 @ret = $try->();
99 } elsif ( defined $wantarray ) {
100 $ret[0] = $try->();
101 } else {
10221µs28.86ms $try->();
# spent 8.86ms making 2 calls to Module::Implementation::try {...} , avg 4.43ms/call
103 };
104
10521µs return 1; # properly set $failed to false
106 };
107
108 # preserve the current error and reset the original value of $@
10920s $error = $@;
11021µs $@ = $prev_error;
111
112 # at this point $failed contains a true value if the eval died, even if some
113 # destructor overwrote $@ as the eval was unwinding.
11421µs if ( $failed ) {
115 # pass $error to the finally blocks
116 push @$_, $error for @{$_finally_guards{guards}};
117
118 # if we got an error, invoke the catch block.
119 if ( $catch ) {
120 # This works like given($error), but is backwards compatible and
121 # sets $_ in the dynamic scope for the body of C<$catch>
122 for ($error) {
123 return $catch->($error);
124 }
125
126 # in case when() was used without an explicit return, the C<for>
127 # loop will be aborted and there's no useful return value
128 }
129
130 return;
131 } else {
132 # no failure, $@ is back to what it was, everything is fine
133210µs return $wantarray ? @ret : $ret[0];
134 }
135}
136
137
# spent 34µs (19+15) within Try::Tiny::catch which was called 2 times, avg 17µs/call: # 2 times (19µs+15µs) by Module::Implementation::_load_implementation at line 98 of Module/Implementation.pm, avg 17µs/call
sub catch (&;@) {
13821µs my ( $block, @rest ) = @_;
139
14021µs croak 'Useless bare catch()' unless wantarray;
141
142224µs215µs _subname(caller().'::catch {...} ' => $block)
# spent 15µs making 2 calls to Sub::Util::set_subname, avg 8µs/call
143 if _HAS_SUBNAME;
144 return (
145210µs bless(\$block, 'Try::Tiny::Catch'),
146 @rest,
147 );
148}
149
150sub finally (&;@) {
151 my ( $block, @rest ) = @_;
152
153 croak 'Useless bare finally()' unless wantarray;
154
155 _subname(caller().'::finally {...} ' => $block)
156 if _HAS_SUBNAME;
157 return (
158 bless(\$block, 'Try::Tiny::Finally'),
159 @rest,
160 );
161}
162
163{
164 package # hide from PAUSE
165 Try::Tiny::ScopeGuard;
166
1672140µs289µs
# spent 49µs (9+40) within Try::Tiny::ScopeGuard::BEGIN@167 which was called: # once (9µs+40µs) by Module::Implementation::BEGIN@9 at line 167
use constant UNSTABLE_DOLLARAT => ("$]" < '5.013002') ? 1 : 0;
# spent 49µs making 1 call to Try::Tiny::ScopeGuard::BEGIN@167 # spent 40µs making 1 call to constant::import
168
169 sub _new {
170 shift;
171 bless [ @_ ];
172 }
173
174 sub DESTROY {
175 my ($code, @args) = @{ $_[0] };
176
177 local $@ if UNSTABLE_DOLLARAT;
178 eval {
179 $code->(@args);
180 1;
181 } or do {
182 warn
183 "Execution of finally() block $code resulted in an exception, which "
184 . '*CAN NOT BE PROPAGATED* due to fundamental limitations of Perl. '
185 . 'Your program will continue as if this event never took place. '
186 . "Original exception text follows:\n\n"
187 . (defined $@ ? $@ : '$@ left undefined...')
188 . "\n"
189 ;
190 }
191 }
192}
193
19411µs__PACKAGE__
195__END__
19616µs