| Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Sub/Install.pm |
| Statements | Executed 154 statements in 1.31ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 6 | 1 | 1 | 88µs | 119µs | Sub::Install::__ANON__[:100] |
| 6 | 2 | 1 | 77µs | 231µs | Sub::Install::__ANON__[:57] |
| 1 | 1 | 1 | 38µs | 74µs | Sub::Install::BEGIN@115 |
| 6 | 1 | 1 | 31µs | 31µs | Sub::Install::__ANON__[:112] |
| 6 | 1 | 1 | 23µs | 36µs | Sub::Install::_CODELIKE |
| 3 | 3 | 1 | 14µs | 18µs | Sub::Install::_do_with_warn |
| 2 | 2 | 2 | 12µs | 12µs | Sub::Install::exporter |
| 1 | 1 | 1 | 12µs | 14µs | Sub::Install::BEGIN@64 |
| 1 | 1 | 1 | 10µs | 21µs | Data::OptList::BEGIN@1 |
| 1 | 1 | 1 | 9µs | 15µs | Sub::Install::BEGIN@174 |
| 3 | 3 | 1 | 8µs | 8µs | Sub::Install::__ANON__[:101] |
| 1 | 1 | 1 | 8µs | 19µs | Sub::Install::BEGIN@109 |
| 1 | 1 | 1 | 8µs | 41µs | Sub::Install::BEGIN@9 |
| 2 | 2 | 1 | 7µs | 7µs | Sub::Install::_build_public_installer |
| 1 | 1 | 1 | 7µs | 10µs | Data::OptList::BEGIN@2 |
| 1 | 1 | 1 | 6µs | 7µs | Sub::Install::BEGIN@73 |
| 3 | 3 | 1 | 6µs | 6µs | Sub::Install::_installer |
| 3 | 3 | 1 | 3µs | 3µs | Sub::Install::CORE:qr (opcode) |
| 1 | 1 | 1 | 3µs | 3µs | Sub::Install::BEGIN@10 |
| 0 | 0 | 0 | 0s | 0s | Sub::Install::__ANON__[:153] |
| 0 | 0 | 0 | 0s | 0s | Sub::Install::__ANON__[:171] |
| 0 | 0 | 0 | 0s | 0s | Sub::Install::__ANON__[:81] |
| 0 | 0 | 0 | 0s | 0s | Sub::Install::__ANON__[:98] |
| 0 | 0 | 0 | 0s | 0s | Sub::Install::_name_of_code |
| 0 | 0 | 0 | 0s | 0s | Sub::Install::install_installers |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | 2 | 17µs | 2 | 32µs | # spent 21µs (10+11) within Data::OptList::BEGIN@1 which was called:
# once (10µs+11µs) by Data::OptList::BEGIN@11 at line 1 # spent 21µs making 1 call to Data::OptList::BEGIN@1
# spent 11µs making 1 call to strict::import |
| 2 | 2 | 31µs | 2 | 13µs | # spent 10µs (7+3) within Data::OptList::BEGIN@2 which was called:
# once (7µs+3µs) by Data::OptList::BEGIN@11 at line 2 # spent 10µs making 1 call to Data::OptList::BEGIN@2
# spent 3µs making 1 call to warnings::import |
| 3 | package Sub::Install; | ||||
| 4 | { | ||||
| 5 | 2 | 900ns | $Sub::Install::VERSION = '0.927'; | ||
| 6 | } | ||||
| 7 | # ABSTRACT: install subroutines into packages easily | ||||
| 8 | |||||
| 9 | 2 | 19µs | 2 | 75µs | # spent 41µs (8+34) within Sub::Install::BEGIN@9 which was called:
# once (8µs+34µs) by Data::OptList::BEGIN@11 at line 9 # spent 41µs making 1 call to Sub::Install::BEGIN@9
# spent 34µs making 1 call to Exporter::import |
| 10 | 2 | 307µs | 1 | 3µs | # spent 3µs within Sub::Install::BEGIN@10 which was called:
# once (3µs+0s) by Data::OptList::BEGIN@11 at line 10 # spent 3µs making 1 call to Sub::Install::BEGIN@10 |
| 11 | |||||
| 12 | |||||
| 13 | sub _name_of_code { | ||||
| 14 | my ($code) = @_; | ||||
| 15 | require B; | ||||
| 16 | my $name = B::svref_2object($code)->GV->NAME; | ||||
| 17 | return $name unless $name =~ /\A__ANON__/; | ||||
| 18 | return; | ||||
| 19 | } | ||||
| 20 | |||||
| 21 | # See also Params::Util, to which this code was donated. | ||||
| 22 | # spent 36µs (23+13) within Sub::Install::_CODELIKE which was called 6 times, avg 6µs/call:
# 6 times (23µs+13µs) by Sub::Install::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Sub/Install.pm:57] at line 42, avg 6µs/call | ||||
| 23 | 6 | 43µs | 6 | 12µs | (Scalar::Util::reftype($_[0])||'') eq 'CODE' # spent 12µs making 6 calls to Scalar::Util::reftype, avg 2µs/call |
| 24 | || Scalar::Util::blessed($_[0]) | ||||
| 25 | && (overload::Method($_[0],'&{}') ? $_[0] : undef); | ||||
| 26 | } | ||||
| 27 | |||||
| 28 | # do the heavy lifting | ||||
| 29 | sub _build_public_installer { | ||||
| 30 | 2 | 400ns | my ($installer) = @_; | ||
| 31 | |||||
| 32 | # spent 231µs (77+155) within Sub::Install::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Sub/Install.pm:57] which was called 6 times, avg 39µs/call:
# 5 times (60µs+114µs) by Sub::Exporter::default_installer at line 442 of Sub/Exporter.pm, avg 35µs/call
# once (17µs+40µs) by Sub::Exporter::setup_exporter at line 198 of Sub/Exporter.pm | ||||
| 33 | 6 | 1µs | my ($arg) = @_; | ||
| 34 | 6 | 18µs | my ($calling_pkg) = caller(0); | ||
| 35 | |||||
| 36 | # I'd rather use ||= but I'm whoring for Devel::Cover. | ||||
| 37 | 18 | 11µs | for (qw(into from)) { $arg->{$_} = $calling_pkg unless $arg->{$_} } | ||
| 38 | |||||
| 39 | # This is the only absolutely required argument, in many cases. | ||||
| 40 | 6 | 1µs | Carp::croak "named argument 'code' is not optional" unless $arg->{code}; | ||
| 41 | |||||
| 42 | 6 | 8µs | 6 | 36µs | if (_CODELIKE($arg->{code})) { # spent 36µs making 6 calls to Sub::Install::_CODELIKE, avg 6µs/call |
| 43 | $arg->{as} ||= _name_of_code($arg->{code}); | ||||
| 44 | } else { | ||||
| 45 | Carp::croak | ||||
| 46 | "couldn't find subroutine named $arg->{code} in package $arg->{from}" | ||||
| 47 | unless my $code = $arg->{from}->can($arg->{code}); | ||||
| 48 | |||||
| 49 | $arg->{as} = $arg->{code} unless $arg->{as}; | ||||
| 50 | $arg->{code} = $code; | ||||
| 51 | } | ||||
| 52 | |||||
| 53 | 6 | 800ns | Carp::croak "couldn't determine name under which to install subroutine" | ||
| 54 | unless $arg->{as}; | ||||
| 55 | |||||
| 56 | 6 | 21µs | 6 | 119µs | $installer->(@$arg{qw(into as code) }); # spent 119µs making 6 calls to Sub::Install::__ANON__[Sub/Install.pm:100], avg 20µs/call |
| 57 | } | ||||
| 58 | 2 | 11µs | } | ||
| 59 | |||||
| 60 | # do the ugly work | ||||
| 61 | |||||
| 62 | 1 | 100ns | my $_misc_warn_re; | ||
| 63 | 1 | 0s | my $_redef_warn_re; | ||
| 64 | # spent 14µs (12+2) within Sub::Install::BEGIN@64 which was called:
# once (12µs+2µs) by Data::OptList::BEGIN@11 at line 70 | ||||
| 65 | 1 | 7µs | 1 | 1µs | $_misc_warn_re = qr/ # spent 1µs making 1 call to Sub::Install::CORE:qr |
| 66 | Prototype\ mismatch:\ sub\ .+? | | ||||
| 67 | Constant subroutine \S+ redefined | ||||
| 68 | /x; | ||||
| 69 | 1 | 9µs | 1 | 800ns | $_redef_warn_re = qr/Subroutine\ \S+\ redefined/x; # spent 800ns making 1 call to Sub::Install::CORE:qr |
| 70 | 1 | 29µs | 1 | 14µs | } # spent 14µs making 1 call to Sub::Install::BEGIN@64 |
| 71 | |||||
| 72 | 1 | 0s | my $eow_re; | ||
| 73 | 1 | 238µs | 2 | 8µs | # spent 7µs (6+1) within Sub::Install::BEGIN@73 which was called:
# once (6µs+1µs) by Data::OptList::BEGIN@11 at line 73 # spent 7µs making 1 call to Sub::Install::BEGIN@73
# spent 1µs making 1 call to Sub::Install::CORE:qr |
| 74 | |||||
| 75 | sub _do_with_warn { | ||||
| 76 | 3 | 700ns | my ($arg) = @_; | ||
| 77 | 3 | 2µs | my $code = delete $arg->{code}; | ||
| 78 | # spent 8µs within Sub::Install::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Sub/Install.pm:101] which was called 3 times, avg 3µs/call:
# once (4µs+0s) by Sub::Install::_do_with_warn at line 102
# once (2µs+0s) by Sub::Install::BEGIN@115 at line 120
# once (2µs+0s) by Sub::Install::BEGIN@115 at line 127 | ||||
| 79 | 3 | 400ns | my $code = shift; | ||
| 80 | # spent 119µs (88+31) within Sub::Install::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Sub/Install.pm:100] which was called 6 times, avg 20µs/call:
# 6 times (88µs+31µs) by Sub::Install::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Sub/Install.pm:57] at line 56, avg 20µs/call | ||||
| 81 | 6 | 14µs | my $warn = $SIG{__WARN__} ? $SIG{__WARN__} : sub { warn @_ }; ## no critic | ||
| 82 | local $SIG{__WARN__} = sub { | ||||
| 83 | my ($error) = @_; | ||||
| 84 | for (@{ $arg->{suppress} }) { | ||||
| 85 | return if $error =~ $_; | ||||
| 86 | } | ||||
| 87 | for (@{ $arg->{croak} }) { | ||||
| 88 | if (my ($base_error) = $error =~ /\A($_) $eow_re/x) { | ||||
| 89 | Carp::croak $base_error; | ||||
| 90 | } | ||||
| 91 | } | ||||
| 92 | for (@{ $arg->{carp} }) { | ||||
| 93 | if (my ($base_error) = $error =~ /\A($_) $eow_re/x) { | ||||
| 94 | return $warn->(Carp::shortmess $base_error); | ||||
| 95 | } | ||||
| 96 | } | ||||
| 97 | ($arg->{default} || $warn)->($error); | ||||
| 98 | 6 | 22µs | }; | ||
| 99 | 6 | 49µs | 6 | 31µs | $code->(@_); # spent 31µs making 6 calls to Sub::Install::__ANON__[Sub/Install.pm:112], avg 5µs/call |
| 100 | 3 | 13µs | }; | ||
| 101 | 3 | 4µs | }; | ||
| 102 | 3 | 6µs | 1 | 4µs | return $wants_code->($code) if $code; # spent 4µs making 1 call to Sub::Install::__ANON__[Sub/Install.pm:101] |
| 103 | 2 | 7µs | return $wants_code; | ||
| 104 | } | ||||
| 105 | |||||
| 106 | sub _installer { | ||||
| 107 | # spent 31µs within Sub::Install::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Sub/Install.pm:112] which was called 6 times, avg 5µs/call:
# 6 times (31µs+0s) by Sub::Install::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Sub/Install.pm:100] at line 99, avg 5µs/call | ||||
| 108 | 6 | 2µs | my ($pkg, $name, $code) = @_; | ||
| 109 | 2 | 110µs | 2 | 30µs | # spent 19µs (8+11) within Sub::Install::BEGIN@109 which was called:
# once (8µs+11µs) by Data::OptList::BEGIN@11 at line 109 # spent 19µs making 1 call to Sub::Install::BEGIN@109
# spent 11µs making 1 call to strict::unimport |
| 110 | 6 | 19µs | *{"$pkg\::$name"} = $code; | ||
| 111 | 6 | 16µs | return $code; | ||
| 112 | } | ||||
| 113 | 3 | 10µs | } | ||
| 114 | |||||
| 115 | # spent 74µs (38+35) within Sub::Install::BEGIN@115 which was called:
# once (38µs+35µs) by Data::OptList::BEGIN@11 at line 133 | ||||
| 116 | 1 | 3µs | 1 | 5µs | *_ignore_warnings = _do_with_warn({ # spent 5µs making 1 call to Sub::Install::_do_with_warn |
| 117 | carp => [ $_misc_warn_re, $_redef_warn_re ] | ||||
| 118 | }); | ||||
| 119 | |||||
| 120 | 1 | 3µs | 3 | 10µs | *install_sub = _build_public_installer(_ignore_warnings(_installer)); # spent 5µs making 1 call to Sub::Install::_build_public_installer
# spent 2µs making 1 call to Sub::Install::__ANON__[Sub/Install.pm:101]
# spent 2µs making 1 call to Sub::Install::_installer |
| 121 | |||||
| 122 | 1 | 2µs | 1 | 3µs | *_carp_warnings = _do_with_warn({ # spent 3µs making 1 call to Sub::Install::_do_with_warn |
| 123 | carp => [ $_misc_warn_re ], | ||||
| 124 | suppress => [ $_redef_warn_re ], | ||||
| 125 | }); | ||||
| 126 | |||||
| 127 | 1 | 3µs | 3 | 6µs | *reinstall_sub = _build_public_installer(_carp_warnings(_installer)); # spent 2µs making 1 call to Sub::Install::__ANON__[Sub/Install.pm:101]
# spent 2µs making 1 call to Sub::Install::_build_public_installer
# spent 2µs making 1 call to Sub::Install::_installer |
| 128 | |||||
| 129 | 1 | 5µs | 2 | 12µs | *_install_fatal = _do_with_warn({ # spent 10µs making 1 call to Sub::Install::_do_with_warn
# spent 2µs making 1 call to Sub::Install::_installer |
| 130 | code => _installer, | ||||
| 131 | croak => [ $_redef_warn_re ], | ||||
| 132 | }); | ||||
| 133 | 1 | 197µs | 1 | 74µs | } # spent 74µs making 1 call to Sub::Install::BEGIN@115 |
| 134 | |||||
| 135 | |||||
| 136 | sub install_installers { | ||||
| 137 | my ($into) = @_; | ||||
| 138 | |||||
| 139 | for my $method (qw(install_sub reinstall_sub)) { | ||||
| 140 | my $code = sub { | ||||
| 141 | my ($package, $subs) = @_; | ||||
| 142 | my ($caller) = caller(0); | ||||
| 143 | my $return; | ||||
| 144 | for (my ($name, $sub) = %$subs) { | ||||
| 145 | $return = Sub::Install->can($method)->({ | ||||
| 146 | code => $sub, | ||||
| 147 | from => $caller, | ||||
| 148 | into => $package, | ||||
| 149 | as => $name | ||||
| 150 | }); | ||||
| 151 | } | ||||
| 152 | return $return; | ||||
| 153 | }; | ||||
| 154 | install_sub({ code => $code, into => $into, as => $method }); | ||||
| 155 | } | ||||
| 156 | } | ||||
| 157 | |||||
| 158 | |||||
| 159 | # spent 12µs within Sub::Install::exporter which was called 2 times, avg 6µs/call:
# once (6µs+0s) by Sub::Install::BEGIN@174 at line 174
# once (6µs+0s) by Data::OptList::BEGIN@100 at line 101 of Data/OptList.pm | ||||
| 160 | 2 | 700ns | my ($arg) = @_; | ||
| 161 | |||||
| 162 | 2 | 6µs | my %is_exported = map { $_ => undef } @{ $arg->{exports} }; | ||
| 163 | |||||
| 164 | sub { | ||||
| 165 | my $class = shift; | ||||
| 166 | my $target = caller; | ||||
| 167 | for (@_) { | ||||
| 168 | Carp::croak "'$_' is not exported by $class" if !exists $is_exported{$_}; | ||||
| 169 | install_sub({ code => $_, from => $class, into => $target }); | ||||
| 170 | } | ||||
| 171 | } | ||||
| 172 | 2 | 14µs | } | ||
| 173 | |||||
| 174 | 1 | 26µs | 2 | 21µs | # spent 15µs (9+6) within Sub::Install::BEGIN@174 which was called:
# once (9µs+6µs) by Data::OptList::BEGIN@11 at line 174 # spent 15µs making 1 call to Sub::Install::BEGIN@174
# spent 6µs making 1 call to Sub::Install::exporter |
| 175 | |||||
| 176 | |||||
| 177 | 1 | 3µs | 1; | ||
| 178 | |||||
| 179 | __END__ | ||||
sub Sub::Install::CORE:qr; # opcode |