| Filename | /home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/Try/Tiny.pm |
| Statements | Executed 139159 statements in 193ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 5472 | 15 | 11 | 102ms | 20.7s | Try::Tiny::try (recurses: max depth 3, inclusive time 1.55s) |
| 5472 | 15 | 11 | 45.3ms | 83.0ms | Try::Tiny::catch |
| 1 | 1 | 1 | 211µs | 234µs | Try::Tiny::BEGIN@16 |
| 1 | 1 | 1 | 9µs | 9µs | Try::Tiny::BEGIN@2 |
| 1 | 1 | 1 | 8µs | 20µs | Try::Tiny::BEGIN@10 |
| 1 | 1 | 1 | 8µs | 64µs | Try::Tiny::ScopeGuard::BEGIN@161 |
| 1 | 1 | 1 | 6µs | 9µs | Try::Tiny::BEGIN@8 |
| 1 | 1 | 1 | 5µs | 40µs | Try::Tiny::BEGIN@13 |
| 1 | 1 | 1 | 4µs | 6µs | Try::Tiny::BEGIN@7 |
| 0 | 0 | 0 | 0s | 0s | Try::Tiny::ScopeGuard::DESTROY |
| 0 | 0 | 0 | 0s | 0s | Try::Tiny::ScopeGuard::_new |
| 0 | 0 | 0 | 0s | 0s | Try::Tiny::__ANON__[:28] |
| 0 | 0 | 0 | 0s | 0s | Try::Tiny::finally |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Try::Tiny; # git description: v0.23-3-g5ee27f1 | ||||
| 2 | 2 | 32µs | 1 | 9µs | # spent 9µs within Try::Tiny::BEGIN@2 which was called:
# once (9µs+0s) by Module::Implementation::BEGIN@9 at line 2 # spent 9µs making 1 call to Try::Tiny::BEGIN@2 |
| 3 | # ABSTRACT: minimal try/catch with proper preservation of $@ | ||||
| 4 | |||||
| 5 | 1 | 300ns | our $VERSION = '0.24'; | ||
| 6 | |||||
| 7 | 2 | 14µs | 2 | 7µs | # spent 6µs (4+1) within Try::Tiny::BEGIN@7 which was called:
# once (4µs+1µs) by Module::Implementation::BEGIN@9 at line 7 # spent 6µs making 1 call to Try::Tiny::BEGIN@7
# spent 1µs making 1 call to strict::import |
| 8 | 2 | 15µs | 2 | 13µs | # spent 9µs (6+3) within Try::Tiny::BEGIN@8 which was called:
# once (6µs+3µs) by Module::Implementation::BEGIN@9 at line 8 # spent 9µs making 1 call to Try::Tiny::BEGIN@8
# spent 3µs making 1 call to warnings::import |
| 9 | |||||
| 10 | 3 | 37µs | 3 | 32µs | # spent 20µs (8+12) within Try::Tiny::BEGIN@10 which was called:
# once (8µs+12µs) by Module::Implementation::BEGIN@9 at line 10 # spent 20µs making 1 call to Try::Tiny::BEGIN@10
# spent 7µs making 1 call to Exporter::import
# spent 4µs making 1 call to UNIVERSAL::VERSION |
| 11 | 1 | 1µs | our @EXPORT = our @EXPORT_OK = qw(try catch finally); | ||
| 12 | |||||
| 13 | 2 | 114µs | 2 | 75µs | # spent 40µs (5+35) within Try::Tiny::BEGIN@13 which was called:
# once (5µs+35µs) by Module::Implementation::BEGIN@9 at line 13 # spent 40µs making 1 call to Try::Tiny::BEGIN@13
# spent 35µs making 1 call to Exporter::import |
| 14 | 1 | 600ns | $Carp::Internal{+__PACKAGE__}++; | ||
| 15 | |||||
| 16 | # spent 234µs (211+23) within Try::Tiny::BEGIN@16 which was called:
# once (211µs+23µs) by Module::Implementation::BEGIN@9 at line 30 | ||||
| 17 | 1 | 500ns | my $su = $INC{'Sub/Util.pm'} && defined &Sub::Util::set_subname; | ||
| 18 | 1 | 0s | my $sn = $INC{'Sub/Name.pm'} && eval { Sub::Name->VERSION(0.08) }; | ||
| 19 | 1 | 300ns | unless ($su || $sn) { | ||
| 20 | 2 | 68µs | $su = eval { require Sub::Util; } && defined &Sub::Util::set_subname; | ||
| 21 | 1 | 200ns | 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 | ||||
| 28 | 1 | 900ns | : sub { $_[1] }; | ||
| 29 | 1 | 2µs | *_HAS_SUBNAME = ($su || $sn) ? sub(){1} : sub(){0}; | ||
| 30 | 1 | 269µs | 1 | 234µs | } # spent 234µs making 1 call to Try::Tiny::BEGIN@16 |
| 31 | |||||
| 32 | # Need to prototype as @ not $$ because of the way Perl evaluates the prototype. | ||||
| 33 | # Keeping it at $$ means you only ever get 1 sub because we need to eval in a list | ||||
| 34 | # context & not a scalar one | ||||
| 35 | |||||
| 36 | # spent 20.7s (102ms+20.6) within Try::Tiny::try which was called 5472 times, avg 3.78ms/call:
# 1001 times (10.7ms+20.4s) by Search::Elasticsearch::Transport::perform_request at line 41 of Search/Elasticsearch/Transport.pm, avg 20.4ms/call
# 1001 times (29.9ms+128ms) by Search::Elasticsearch::Role::Client::Direct::parse_request at line 38 of Search/Elasticsearch/Role/Client/Direct.pm, avg 157µs/call
# 1001 times (21.7ms+-21.7ms) by Search::Elasticsearch::Role::Serializer::JSON::decode at line 85 of Search/Elasticsearch/Role/Serializer/JSON.pm, avg 0s/call
# 1001 times (24.8ms+-24.8ms) by Search::Elasticsearch::Role::Cxn::pings_ok at line 193 of Search/Elasticsearch/Role/Cxn.pm, avg 0s/call
# 1000 times (10.7ms+21.2ms) by Search::Elasticsearch::Role::Serializer::JSON::encode at line 25 of Search/Elasticsearch/Role/Serializer/JSON.pm, avg 32µs/call
# 193 times (1.37ms+25.3ms) by Class::MOP::Attribute::_process_accessors at line 423 of Class/MOP/Attribute.pm, avg 138µs/call
# 135 times (1.08ms+37.2ms) by Class::MOP::Class::_post_add_attribute at line 904 of Class/MOP/Class.pm, avg 284µs/call
# 56 times (480µs+-480µs) by Class::MOP::Method::Accessor::_generate_reader_method_inline at line 169 of Class/MOP/Method/Accessor.pm, avg 0s/call
# 31 times (284µs+10.9ms) by Class::MOP::Method::Constructor::_generate_constructor_method_inline at line 115 of Class/MOP/Method/Constructor.pm, avg 362µs/call
# 25 times (231µs+-231µs) by Class::MOP::Method::Accessor::_generate_accessor_method_inline at line 127 of Class/MOP/Method/Accessor.pm, avg 0s/call
# 15 times (121µs+-121µs) by Class::MOP::Method::Accessor::_generate_predicate_method_inline at line 230 of Class/MOP/Method/Accessor.pm, avg 0s/call
# 6 times (56µs+-56µs) by Moose::Meta::Method::Accessor::_compile_code at line 41 of Moose/Meta/Method/Accessor.pm, avg 0s/call
# 3 times (45µs+1.87ms) by Module::Implementation::_load_implementation at line 98 of Module/Implementation.pm, avg 638µs/call
# 3 times (21µs+-21µs) by Class::MOP::Method::Accessor::_generate_writer_method_inline at line 202 of Class/MOP/Method/Accessor.pm, avg 0s/call
# once (9µs+109µs) by Moose::Meta::Method::Destructor::_initialize_body at line 100 of Moose/Meta/Method/Destructor.pm | ||||
| 37 | 5472 | 2.89ms | my ( $try, @code_refs ) = @_; | ||
| 38 | |||||
| 39 | # we need to save this here, the eval block will be in scalar context due | ||||
| 40 | # to $failed | ||||
| 41 | 5472 | 1.92ms | my $wantarray = wantarray; | ||
| 42 | |||||
| 43 | # work around perl bug by explicitly initializing these, due to the likelyhood | ||||
| 44 | # this will be used in global destruction (perl rt#119311) | ||||
| 45 | 5472 | 2.02ms | my ( $catch, @finally ) = (); | ||
| 46 | |||||
| 47 | # find labeled blocks in the argument list. | ||||
| 48 | # catch and finally tag the blocks by blessing a scalar reference to them. | ||||
| 49 | 5472 | 4.20ms | foreach my $code_ref (@code_refs) { | ||
| 50 | |||||
| 51 | 5472 | 5.60ms | if ( ref($code_ref) eq 'Try::Tiny::Catch' ) { | ||
| 52 | 5472 | 810µs | croak 'A try() may not be followed by multiple catch() blocks' | ||
| 53 | if $catch; | ||||
| 54 | 5472 | 1.68ms | $catch = ${$code_ref}; | ||
| 55 | } elsif ( ref($code_ref) eq 'Try::Tiny::Finally' ) { | ||||
| 56 | push @finally, ${$code_ref}; | ||||
| 57 | } else { | ||||
| 58 | croak( | ||||
| 59 | 'try() encountered an unexpected argument (' | ||||
| 60 | . ( defined $code_ref ? $code_ref : 'undef' ) | ||||
| 61 | . ') - perhaps a missing semi-colon before or' | ||||
| 62 | ); | ||||
| 63 | } | ||||
| 64 | } | ||||
| 65 | |||||
| 66 | # FIXME consider using local $SIG{__DIE__} to accumulate all errors. It's | ||||
| 67 | # not perfect, but we could provide a list of additional errors for | ||||
| 68 | # $catch->(); | ||||
| 69 | |||||
| 70 | # name the blocks if we have Sub::Name installed | ||||
| 71 | 5472 | 2.19ms | my $caller = caller; | ||
| 72 | 5472 | 34.6ms | 5472 | 19.8ms | _subname("${caller}::try {...} " => $try) # spent 19.8ms making 5472 calls to Sub::Util::set_subname, avg 4µs/call |
| 73 | if _HAS_SUBNAME; | ||||
| 74 | |||||
| 75 | # save the value of $@ so we can set $@ back to it in the beginning of the eval | ||||
| 76 | # and restore $@ after the eval finishes | ||||
| 77 | 5472 | 2.02ms | my $prev_error = $@; | ||
| 78 | |||||
| 79 | 5472 | 912µs | my ( @ret, $error ); | ||
| 80 | |||||
| 81 | # failed will be true if the eval dies, because 1 will not be returned | ||||
| 82 | # from the eval body | ||||
| 83 | 5472 | 10.3ms | my $failed = not eval { | ||
| 84 | 5472 | 1.29ms | $@ = $prev_error; | ||
| 85 | |||||
| 86 | # evaluate the try block in the correct context | ||||
| 87 | 5472 | 6.71ms | 3139 | 1.51s | if ( $wantarray ) { # spent 1.44s making 1001 calls to Search::Elasticsearch::Role::Cxn::try {...} , avg 1.44ms/call
# spent 34.1ms making 2001 calls to Search::Elasticsearch::Role::Serializer::JSON::try {...} , avg 17µs/call
# spent 19.5ms making 99 calls to Class::MOP::Method::Accessor::try {...} , avg 197µs/call
# spent 10.9ms making 31 calls to Class::MOP::Method::Constructor::try {...} , avg 351µs/call
# spent 1.66ms making 6 calls to Moose::Meta::Method::Accessor::try {...} , avg 276µs/call
# spent 106µs making 1 call to Moose::Meta::Method::Destructor::try {...} |
| 88 | @ret = $try->(); | ||||
| 89 | } elsif ( defined $wantarray ) { | ||||
| 90 | $ret[0] = $try->(); | ||||
| 91 | } else { | ||||
| 92 | 2333 | 2.13ms | 2333 | 20.6s | $try->(); # spent 20.4s making 1001 calls to Search::Elasticsearch::Transport::try {...} , avg 20.4ms/call
# spent 123ms making 1001 calls to Search::Elasticsearch::Role::Client::Direct::try {...} , avg 123µs/call
# spent 37.0ms making 135 calls to Class::MOP::Class::try {...} , avg 274µs/call
# spent 34.0ms making 193 calls to Class::MOP::Attribute::try {...} , avg 176µs/call
# spent 1.86ms making 3 calls to Module::Implementation::try {...} , avg 620µs/call |
| 93 | }; | ||||
| 94 | |||||
| 95 | 5472 | 2.93ms | return 1; # properly set $failed to false | ||
| 96 | }; | ||||
| 97 | |||||
| 98 | # preserve the current error and reset the original value of $@ | ||||
| 99 | 5472 | 1.74ms | $error = $@; | ||
| 100 | 5472 | 1.34ms | $@ = $prev_error; | ||
| 101 | |||||
| 102 | # set up a scope guard to invoke the finally block at the end | ||||
| 103 | my @guards = | ||||
| 104 | 5472 | 3.67ms | map { Try::Tiny::ScopeGuard->_new($_, $failed ? $error : ()) } | ||
| 105 | @finally; | ||||
| 106 | |||||
| 107 | # at this point $failed contains a true value if the eval died, even if some | ||||
| 108 | # destructor overwrote $@ as the eval was unwinding. | ||||
| 109 | 5472 | 1.39ms | if ( $failed ) { | ||
| 110 | # if we got an error, invoke the catch block. | ||||
| 111 | if ( $catch ) { | ||||
| 112 | # This works like given($error), but is backwards compatible and | ||||
| 113 | # sets $_ in the dynamic scope for the body of C<$catch> | ||||
| 114 | for ($error) { | ||||
| 115 | return $catch->($error); | ||||
| 116 | } | ||||
| 117 | |||||
| 118 | # in case when() was used without an explicit return, the C<for> | ||||
| 119 | # loop will be aborted and there's no useful return value | ||||
| 120 | } | ||||
| 121 | |||||
| 122 | return; | ||||
| 123 | } else { | ||||
| 124 | # no failure, $@ is back to what it was, everything is fine | ||||
| 125 | 5472 | 16.3ms | return $wantarray ? @ret : $ret[0]; | ||
| 126 | } | ||||
| 127 | } | ||||
| 128 | |||||
| 129 | # spent 83.0ms (45.3+37.7) within Try::Tiny::catch which was called 5472 times, avg 15µs/call:
# 1001 times (21.8ms+10.1ms) by Search::Elasticsearch::Role::Client::Direct::parse_request at line 38 of Search/Elasticsearch/Role/Client/Direct.pm, avg 32µs/call
# 1001 times (12.3ms+12.8ms) by Search::Elasticsearch::Role::Serializer::JSON::decode at line 85 of Search/Elasticsearch/Role/Serializer/JSON.pm, avg 25µs/call
# 1001 times (3.07ms+4.18ms) by Search::Elasticsearch::Role::Cxn::pings_ok at line 193 of Search/Elasticsearch/Role/Cxn.pm, avg 7µs/call
# 1001 times (2.90ms+3.69ms) by Search::Elasticsearch::Transport::perform_request at line 41 of Search/Elasticsearch/Transport.pm, avg 7µs/call
# 1000 times (3.86ms+5.53ms) by Search::Elasticsearch::Role::Serializer::JSON::encode at line 25 of Search/Elasticsearch/Role/Serializer/JSON.pm, avg 9µs/call
# 193 times (522µs+530µs) by Class::MOP::Attribute::_process_accessors at line 423 of Class/MOP/Attribute.pm, avg 5µs/call
# 135 times (429µs+451µs) by Class::MOP::Class::_post_add_attribute at line 904 of Class/MOP/Class.pm, avg 7µs/call
# 56 times (137µs+153µs) by Class::MOP::Method::Accessor::_generate_reader_method_inline at line 169 of Class/MOP/Method/Accessor.pm, avg 5µs/call
# 31 times (104µs+127µs) by Class::MOP::Method::Constructor::_generate_constructor_method_inline at line 115 of Class/MOP/Method/Constructor.pm, avg 7µs/call
# 25 times (62µs+68µs) by Class::MOP::Method::Accessor::_generate_accessor_method_inline at line 127 of Class/MOP/Method/Accessor.pm, avg 5µs/call
# 15 times (35µs+36µs) by Class::MOP::Method::Accessor::_generate_predicate_method_inline at line 230 of Class/MOP/Method/Accessor.pm, avg 5µs/call
# 6 times (16µs+22µs) by Moose::Meta::Method::Accessor::_compile_code at line 41 of Moose/Meta/Method/Accessor.pm, avg 6µs/call
# 3 times (23µs+28µs) by Module::Implementation::_load_implementation at line 98 of Module/Implementation.pm, avg 17µs/call
# 3 times (7µs+7µs) by Class::MOP::Method::Accessor::_generate_writer_method_inline at line 202 of Class/MOP/Method/Accessor.pm, avg 5µs/call
# once (3µs+4µs) by Moose::Meta::Method::Destructor::_initialize_body at line 100 of Moose/Meta/Method/Destructor.pm | ||||
| 130 | 5472 | 2.38ms | my ( $block, @rest ) = @_; | ||
| 131 | |||||
| 132 | 5472 | 1.41ms | croak 'Useless bare catch()' unless wantarray; | ||
| 133 | |||||
| 134 | 5472 | 3.75ms | my $caller = caller; | ||
| 135 | 5472 | 62.6ms | 5472 | 37.7ms | _subname("${caller}::catch {...} " => $block) # spent 37.7ms making 5472 calls to Sub::Util::set_subname, avg 7µs/call |
| 136 | if _HAS_SUBNAME; | ||||
| 137 | return ( | ||||
| 138 | 5472 | 15.5ms | bless(\$block, 'Try::Tiny::Catch'), | ||
| 139 | @rest, | ||||
| 140 | ); | ||||
| 141 | } | ||||
| 142 | |||||
| 143 | sub finally (&;@) { | ||||
| 144 | my ( $block, @rest ) = @_; | ||||
| 145 | |||||
| 146 | croak 'Useless bare finally()' unless wantarray; | ||||
| 147 | |||||
| 148 | my $caller = caller; | ||||
| 149 | _subname("${caller}::finally {...} " => $block) | ||||
| 150 | if _HAS_SUBNAME; | ||||
| 151 | return ( | ||||
| 152 | bless(\$block, 'Try::Tiny::Finally'), | ||||
| 153 | @rest, | ||||
| 154 | ); | ||||
| 155 | } | ||||
| 156 | |||||
| 157 | { | ||||
| 158 | package # hide from PAUSE | ||||
| 159 | Try::Tiny::ScopeGuard; | ||||
| 160 | |||||
| 161 | 2 | 96µs | 2 | 120µs | # spent 64µs (8+56) within Try::Tiny::ScopeGuard::BEGIN@161 which was called:
# once (8µs+56µs) by Module::Implementation::BEGIN@9 at line 161 # spent 64µs making 1 call to Try::Tiny::ScopeGuard::BEGIN@161
# spent 56µs making 1 call to constant::import |
| 162 | |||||
| 163 | sub _new { | ||||
| 164 | shift; | ||||
| 165 | bless [ @_ ]; | ||||
| 166 | } | ||||
| 167 | |||||
| 168 | sub DESTROY { | ||||
| 169 | my ($code, @args) = @{ $_[0] }; | ||||
| 170 | |||||
| 171 | local $@ if UNSTABLE_DOLLARAT; | ||||
| 172 | eval { | ||||
| 173 | $code->(@args); | ||||
| 174 | 1; | ||||
| 175 | } or do { | ||||
| 176 | warn | ||||
| 177 | "Execution of finally() block $code resulted in an exception, which " | ||||
| 178 | . '*CAN NOT BE PROPAGATED* due to fundamental limitations of Perl. ' | ||||
| 179 | . 'Your program will continue as if this event never took place. ' | ||||
| 180 | . "Original exception text follows:\n\n" | ||||
| 181 | . (defined $@ ? $@ : '$@ left undefined...') | ||||
| 182 | . "\n" | ||||
| 183 | ; | ||||
| 184 | } | ||||
| 185 | } | ||||
| 186 | } | ||||
| 187 | |||||
| 188 | 1 | 300ns | __PACKAGE__ | ||
| 189 | __END__ | ||||
| 190 | 1 | 3µs |