| Filename | /home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Try/Tiny.pm |
| Statements | Executed 25661 statements in 146ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1194 | 13 | 9 | 115ms | 3.13s | Try::Tiny::try (recurses: max depth 4, inclusive time 2.72s) |
| 1188 | 11 | 7 | 24.0ms | 24.0ms | Try::Tiny::catch |
| 1 | 1 | 1 | 71µs | 89µs | Try::Tiny::BEGIN@3 |
| 1 | 1 | 1 | 50µs | 50µs | Try::Tiny::BEGIN@8 |
| 1 | 1 | 1 | 43µs | 407µs | Try::Tiny::BEGIN@6 |
| 1 | 1 | 1 | 41µs | 254µs | Try::Tiny::BEGIN@46 |
| 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::finally |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Try::Tiny; | ||||
| 2 | |||||
| 3 | 3 | 113µs | 2 | 107µs | # spent 89µs (71+18) within Try::Tiny::BEGIN@3 which was called:
# once (71µs+18µs) by Class::MOP::BEGIN@14 at line 3 # spent 89µs making 1 call to Try::Tiny::BEGIN@3
# spent 18µs making 1 call to strict::import |
| 4 | #use warnings; | ||||
| 5 | |||||
| 6 | 3 | 301µs | 2 | 772µs | # spent 407µs (43+365) within Try::Tiny::BEGIN@6 which was called:
# once (43µs+365µs) by Class::MOP::BEGIN@14 at line 6 # spent 407µs making 1 call to Try::Tiny::BEGIN@6
# spent 365µs making 1 call to vars::import |
| 7 | |||||
| 8 | # spent 50µs within Try::Tiny::BEGIN@8 which was called:
# once (50µs+0s) by Class::MOP::BEGIN@14 at line 11 | ||||
| 9 | 2 | 52µs | require Exporter; | ||
| 10 | @ISA = qw(Exporter); | ||||
| 11 | 1 | 419µs | 1 | 50µs | } # spent 50µs making 1 call to Try::Tiny::BEGIN@8 |
| 12 | |||||
| 13 | 1 | 4µs | $VERSION = "0.07"; | ||
| 14 | |||||
| 15 | 1 | 57µs | $VERSION = eval $VERSION; # spent 10µs executing statements in string eval | ||
| 16 | |||||
| 17 | 1 | 10µs | @EXPORT = @EXPORT_OK = qw(try catch finally); | ||
| 18 | |||||
| 19 | 1 | 5µs | $Carp::Internal{+__PACKAGE__}++; | ||
| 20 | |||||
| 21 | # Need to prototype as @ not $$ because of the way Perl evaluates the prototype. | ||||
| 22 | # Keeping it at $$ means you only ever get 1 sub because we need to eval in a list | ||||
| 23 | # context & not a scalar one | ||||
| 24 | |||||
| 25 | # spent 3.13s (115ms+3.01) within Try::Tiny::try which was called 1194 times, avg 2.62ms/call:
# 361 times (33.0ms+134ms) by Class::MOP::Attribute::_process_accessors at line 404 of Class/MOP/Attribute.pm, avg 462µs/call
# 239 times (23.2ms+1.84s) by Class::MOP::Class::_post_add_attribute at line 936 of Class/MOP/Class.pm, avg 7.78ms/call
# 198 times (19.3ms+-19.3ms) by Moose::Meta::Method::Accessor::_compile_code at line 36 of Moose/Meta/Method/Accessor.pm, avg 0s/call
# 150 times (15.5ms+-15.5ms) by Class::MOP::Method::Accessor::_generate_reader_method_inline at line 155 of Class/MOP/Method/Accessor.pm, avg 0s/call
# 55 times (5.46ms+179ms) by Class::MOP::Method::Constructor::_generate_constructor_method_inline at line 126 of Class/MOP/Method/Constructor.pm, avg 3.35ms/call
# 43 times (4.33ms+-4.33ms) by Class::MOP::Method::Accessor::_generate_predicate_method_inline at line 210 of Class/MOP/Method/Accessor.pm, avg 0s/call
# 41 times (4.20ms+-4.20ms) by Class::MOP::Method::Accessor::_generate_accessor_method_inline at line 121 of Class/MOP/Method/Accessor.pm, avg 0s/call
# 34 times (3.47ms+887ms) by Class::MOP::load_first_existing_class at line 125 of Class/MOP.pm, avg 26.2ms/call
# 29 times (2.96ms+-2.96ms) by Class::MOP::Method::Accessor::_generate_clearer_method_inline at line 235 of Class/MOP/Method/Accessor.pm, avg 0s/call
# 24 times (2.21ms+19.2ms) by Moose::Meta::Method::Destructor::_initialize_body at line 102 of Moose/Meta/Method/Destructor.pm, avg 893µs/call
# 14 times (1.40ms+-1.40ms) by Class::MOP::Method::Accessor::_generate_writer_method_inline at line 185 of Class/MOP/Method/Accessor.pm, avg 0s/call
# 5 times (374µs+3.76ms) by Moose::Meta::Attribute::does at line 40 of Moose/Meta/Attribute.pm, avg 827µs/call
# once (90µs+-90µs) by Class::MOP::__ANON__[/home/doy/coding/src/Class-MOP/blib/lib//Class/MOP.pm:118] at line 13 of KiokuDB/Role/UUIDs.pm | ||||
| 26 | 23268 | 115ms | my ( $try, @code_refs ) = @_; | ||
| 27 | |||||
| 28 | # we need to save this here, the eval block will be in scalar context due | ||||
| 29 | # to $failed | ||||
| 30 | my $wantarray = wantarray; | ||||
| 31 | |||||
| 32 | my ( $catch, @finally ); | ||||
| 33 | |||||
| 34 | # find labeled blocks in the argument list. | ||||
| 35 | # catch and finally tag the blocks by blessing a scalar reference to them. | ||||
| 36 | foreach my $code_ref (@code_refs) { | ||||
| 37 | next unless $code_ref; | ||||
| 38 | |||||
| 39 | my $ref = ref($code_ref); | ||||
| 40 | |||||
| 41 | if ( $ref eq 'Try::Tiny::Catch' ) { | ||||
| 42 | $catch = ${$code_ref}; | ||||
| 43 | } elsif ( $ref eq 'Try::Tiny::Finally' ) { | ||||
| 44 | push @finally, ${$code_ref}; | ||||
| 45 | } else { | ||||
| 46 | 3 | 1.11ms | 2 | 468µs | # spent 254µs (41+214) within Try::Tiny::BEGIN@46 which was called:
# once (41µs+214µs) by Class::MOP::BEGIN@14 at line 46 # spent 254µs making 1 call to Try::Tiny::BEGIN@46
# spent 214µs making 1 call to Exporter::import |
| 47 | confess("Unknown code ref type given '${ref}'. Check your usage & try again"); | ||||
| 48 | } | ||||
| 49 | } | ||||
| 50 | |||||
| 51 | # save the value of $@ so we can set $@ back to it in the beginning of the eval | ||||
| 52 | my $prev_error = $@; | ||||
| 53 | |||||
| 54 | my ( @ret, $error, $failed ); | ||||
| 55 | |||||
| 56 | # FIXME consider using local $SIG{__DIE__} to accumulate all errors. It's | ||||
| 57 | # not perfect, but we could provide a list of additional errors for | ||||
| 58 | # $catch->(); | ||||
| 59 | |||||
| 60 | { | ||||
| 61 | # localize $@ to prevent clobbering of previous value by a successful | ||||
| 62 | # eval. | ||||
| 63 | local $@; | ||||
| 64 | |||||
| 65 | # failed will be true if the eval dies, because 1 will not be returned | ||||
| 66 | # from the eval body | ||||
| 67 | $failed = not eval { | ||||
| 68 | $@ = $prev_error; | ||||
| 69 | |||||
| 70 | # evaluate the try block in the correct context | ||||
| 71 | 594 | 2.97s | if ( $wantarray ) { # spent 1.79s making 34 calls to Class::MOP::__ANON__[Class/MOP.pm:118], avg 52.8ms/call
# spent 364ms making 150 calls to Class::MOP::Method::Accessor::__ANON__[Class/MOP/Method/Accessor.pm:152], avg 2.43ms/call
# spent 304ms making 198 calls to Moose::Meta::Method::Accessor::__ANON__[Moose/Meta/Method/Accessor.pm:28], avg 1.53ms/call
# spent 191ms making 55 calls to Class::MOP::Method::Constructor::__ANON__[Class/MOP/Method/Constructor.pm:122], avg 3.48ms/call
# spent 125ms making 41 calls to Class::MOP::Method::Accessor::__ANON__[Class/MOP/Method/Accessor.pm:118], avg 3.05ms/call
# spent 69.2ms making 43 calls to Class::MOP::Method::Accessor::__ANON__[Class/MOP/Method/Accessor.pm:207], avg 1.61ms/call
# spent 53.4ms making 29 calls to Class::MOP::Method::Accessor::__ANON__[Class/MOP/Method/Accessor.pm:232], avg 1.84ms/call
# spent 30.6ms making 14 calls to Class::MOP::Method::Accessor::__ANON__[Class/MOP/Method/Accessor.pm:182], avg 2.18ms/call
# spent 23.3ms making 24 calls to Moose::Meta::Method::Destructor::__ANON__[Moose/Meta/Method/Destructor.pm:94], avg 971µs/call
# spent 9.40ms making 1 call to KiokuDB::Role::UUIDs::__ANON__[KiokuDB/Role/UUIDs.pm:13]
# spent 3.76ms making 5 calls to Moose::Meta::Attribute::__ANON__[Moose/Meta/Attribute.pm:40], avg 753µs/call | ||
| 72 | @ret = $try->(); | ||||
| 73 | } elsif ( defined $wantarray ) { | ||||
| 74 | $ret[0] = $try->(); | ||||
| 75 | } else { | ||||
| 76 | 600 | 2.77s | $try->(); # spent 1.89s making 239 calls to Class::MOP::Class::__ANON__[Class/MOP/Class.pm:932], avg 7.89ms/call
# spent 883ms making 361 calls to Class::MOP::Attribute::__ANON__[Class/MOP/Attribute.pm:401], avg 2.44ms/call | ||
| 77 | }; | ||||
| 78 | |||||
| 79 | return 1; # properly set $fail to false | ||||
| 80 | }; | ||||
| 81 | |||||
| 82 | # copy $@ to $error; when we leave this scope, local $@ will revert $@ | ||||
| 83 | # back to its previous value | ||||
| 84 | $error = $@; | ||||
| 85 | } | ||||
| 86 | |||||
| 87 | # set up a scope guard to invoke the finally block at the end | ||||
| 88 | my @guards = | ||||
| 89 | map { Try::Tiny::ScopeGuard->_new($_, $failed ? $error : ()) } | ||||
| 90 | @finally; | ||||
| 91 | |||||
| 92 | # at this point $failed contains a true value if the eval died, even if some | ||||
| 93 | # destructor overwrote $@ as the eval was unwinding. | ||||
| 94 | if ( $failed ) { | ||||
| 95 | # if we got an error, invoke the catch block. | ||||
| 96 | if ( $catch ) { | ||||
| 97 | # This works like given($error), but is backwards compatible and | ||||
| 98 | # sets $_ in the dynamic scope for the body of C<$catch> | ||||
| 99 | for ($error) { | ||||
| 100 | 3 | 261µs | return $catch->($error); # spent 261µs making 3 calls to Class::MOP::__ANON__[Class/MOP.pm:125], avg 87µs/call | ||
| 101 | } | ||||
| 102 | |||||
| 103 | # in case when() was used without an explicit return, the C<for> | ||||
| 104 | # loop will be aborted and there's no useful return value | ||||
| 105 | } | ||||
| 106 | |||||
| 107 | return; | ||||
| 108 | } else { | ||||
| 109 | # no failure, $@ is back to what it was, everything is fine | ||||
| 110 | return $wantarray ? @ret : $ret[0]; | ||||
| 111 | } | ||||
| 112 | } | ||||
| 113 | |||||
| 114 | # spent 24.0ms within Try::Tiny::catch which was called 1188 times, avg 20µs/call:
# 361 times (7.61ms+0s) by Class::MOP::Attribute::_process_accessors at line 404 of Class/MOP/Attribute.pm, avg 21µs/call
# 239 times (5.33ms+0s) by Class::MOP::Class::_post_add_attribute at line 936 of Class/MOP/Class.pm, avg 22µs/call
# 198 times (3.76ms+0s) by Moose::Meta::Method::Accessor::_compile_code at line 36 of Moose/Meta/Method/Accessor.pm, avg 19µs/call
# 150 times (2.62ms+0s) by Class::MOP::Method::Accessor::_generate_reader_method_inline at line 155 of Class/MOP/Method/Accessor.pm, avg 17µs/call
# 55 times (1.21ms+0s) by Class::MOP::Method::Constructor::_generate_constructor_method_inline at line 126 of Class/MOP/Method/Constructor.pm, avg 22µs/call
# 43 times (810µs+0s) by Class::MOP::Method::Accessor::_generate_predicate_method_inline at line 210 of Class/MOP/Method/Accessor.pm, avg 19µs/call
# 41 times (694µs+0s) by Class::MOP::Method::Accessor::_generate_accessor_method_inline at line 121 of Class/MOP/Method/Accessor.pm, avg 17µs/call
# 34 times (730µs+0s) by Class::MOP::load_first_existing_class at line 125 of Class/MOP.pm, avg 21µs/call
# 29 times (506µs+0s) by Class::MOP::Method::Accessor::_generate_clearer_method_inline at line 235 of Class/MOP/Method/Accessor.pm, avg 17µs/call
# 24 times (490µs+0s) by Moose::Meta::Method::Destructor::_initialize_body at line 102 of Moose/Meta/Method/Destructor.pm, avg 20µs/call
# 14 times (241µs+0s) by Class::MOP::Method::Accessor::_generate_writer_method_inline at line 185 of Class/MOP/Method/Accessor.pm, avg 17µs/call | ||||
| 115 | 2376 | 28.7ms | my ( $block, @rest ) = @_; | ||
| 116 | |||||
| 117 | return ( | ||||
| 118 | bless(\$block, 'Try::Tiny::Catch'), | ||||
| 119 | @rest, | ||||
| 120 | ); | ||||
| 121 | } | ||||
| 122 | |||||
| 123 | sub finally (&;@) { | ||||
| 124 | my ( $block, @rest ) = @_; | ||||
| 125 | |||||
| 126 | return ( | ||||
| 127 | bless(\$block, 'Try::Tiny::Finally'), | ||||
| 128 | @rest, | ||||
| 129 | ); | ||||
| 130 | } | ||||
| 131 | |||||
| 132 | { | ||||
| 133 | 1 | 4µs | package Try::Tiny::ScopeGuard; | ||
| 134 | |||||
| 135 | sub _new { | ||||
| 136 | shift; | ||||
| 137 | bless [ @_ ]; | ||||
| 138 | } | ||||
| 139 | |||||
| 140 | sub DESTROY { | ||||
| 141 | my @guts = @{ shift() }; | ||||
| 142 | my $code = shift @guts; | ||||
| 143 | $code->(@guts); | ||||
| 144 | } | ||||
| 145 | } | ||||
| 146 | |||||
| 147 | __PACKAGE__ | ||||
| 148 | |||||
| 149 | 1 | 17µs | __END__ |