| Filename | /usr/local/share/perl/5.18.2/namespace/autoclean.pm |
| Statements | Executed 176 statements in 1.92ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 1.49ms | 4.06ms | namespace::autoclean::BEGIN@12 |
| 1 | 1 | 1 | 928µs | 1.24ms | namespace::autoclean::_method_check |
| 1 | 1 | 1 | 434µs | 9.34ms | namespace::autoclean::BEGIN@10 |
| 1 | 1 | 1 | 222µs | 2.38ms | namespace::autoclean::__ANON__[:183] |
| 16 | 1 | 1 | 173µs | 272µs | namespace::autoclean::__ANON__[:210] |
| 1 | 1 | 1 | 20µs | 38µs | namespace::autoclean::import |
| 1 | 1 | 1 | 17µs | 34µs | String::Markov::BEGIN@1 |
| 1 | 1 | 1 | 14µs | 120µs | namespace::autoclean::BEGIN@11 |
| 1 | 1 | 1 | 11µs | 28µs | namespace::autoclean::BEGIN@203 |
| 1 | 1 | 1 | 9µs | 15µs | String::Markov::BEGIN@2 |
| 16 | 1 | 1 | 9µs | 9µs | namespace::autoclean::CORE:match (opcode) |
| 0 | 0 | 0 | 0s | 0s | namespace::autoclean::__ANON__[:147] |
| 0 | 0 | 0 | 0s | 0s | namespace::autoclean::__ANON__[:148] |
| 0 | 0 | 0 | 0s | 0s | namespace::autoclean::__ANON__[:149] |
| 0 | 0 | 0 | 0s | 0s | namespace::autoclean::__ANON__[:155] |
| 0 | 0 | 0 | 0s | 0s | namespace::autoclean::__ANON__[:177] |
| 0 | 0 | 0 | 0s | 0s | namespace::autoclean::__ANON__[:179] |
| 0 | 0 | 0 | 0s | 0s | namespace::autoclean::__ANON__[:194] |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | 2 | 40µs | 2 | 51µs | # spent 34µs (17+17) within String::Markov::BEGIN@1 which was called:
# once (17µs+17µs) by String::Markov::BEGIN@9 at line 1 # spent 34µs making 1 call to String::Markov::BEGIN@1
# spent 17µs making 1 call to strict::import |
| 2 | 2 | 56µs | 2 | 21µs | # spent 15µs (9+6) within String::Markov::BEGIN@2 which was called:
# once (9µs+6µs) by String::Markov::BEGIN@9 at line 2 # spent 15µs making 1 call to String::Markov::BEGIN@2
# spent 6µs making 1 call to warnings::import |
| 3 | |||||
| 4 | package namespace::autoclean; # git description: 0.27-4-g47c7088 | ||||
| 5 | # ABSTRACT: Keep imports out of your namespace | ||||
| 6 | # KEYWORDS: namespaces clean dirty imports exports subroutines methods development | ||||
| 7 | |||||
| 8 | 1 | 600ns | our $VERSION = '0.28'; | ||
| 9 | |||||
| 10 | 3 | 158µs | 3 | 9.37ms | # spent 9.34ms (434µs+8.91) within namespace::autoclean::BEGIN@10 which was called:
# once (434µs+8.91ms) by String::Markov::BEGIN@9 at line 10 # spent 9.34ms making 1 call to namespace::autoclean::BEGIN@10
# spent 19µs making 1 call to Sub::Exporter::Progressive::__ANON__[Sub/Exporter/Progressive.pm:40]
# spent 11µs making 1 call to UNIVERSAL::VERSION |
| 11 | 2 | 37µs | 2 | 130µs | # spent 120µs (14+105) within namespace::autoclean::BEGIN@11 which was called:
# once (14µs+105µs) by String::Markov::BEGIN@9 at line 11 # spent 120µs making 1 call to namespace::autoclean::BEGIN@11
# spent 10µs making 1 call to List::Util::import |
| 12 | 3 | 918µs | 3 | 4.41ms | # spent 4.06ms (1.49+2.58) within namespace::autoclean::BEGIN@12 which was called:
# once (1.49ms+2.58ms) by String::Markov::BEGIN@9 at line 12 # spent 4.06ms making 1 call to namespace::autoclean::BEGIN@12
# spent 334µs making 1 call to namespace::clean::import
# spent 12µs making 1 call to UNIVERSAL::VERSION |
| 13 | |||||
| 14 | #pod =head1 SYNOPSIS | ||||
| 15 | #pod | ||||
| 16 | #pod package Foo; | ||||
| 17 | #pod use namespace::autoclean; | ||||
| 18 | #pod use Some::Package qw/imported_function/; | ||||
| 19 | #pod | ||||
| 20 | #pod sub bar { imported_function('stuff') } | ||||
| 21 | #pod | ||||
| 22 | #pod # later on: | ||||
| 23 | #pod Foo->bar; # works | ||||
| 24 | #pod Foo->imported_function; # will fail. imported_function got cleaned after compilation | ||||
| 25 | #pod | ||||
| 26 | #pod =head1 DESCRIPTION | ||||
| 27 | #pod | ||||
| 28 | #pod When you import a function into a Perl package, it will naturally also be | ||||
| 29 | #pod available as a method. | ||||
| 30 | #pod | ||||
| 31 | #pod The C<namespace::autoclean> pragma will remove all imported symbols at the end | ||||
| 32 | #pod of the current package's compile cycle. Functions called in the package itself | ||||
| 33 | #pod will still be bound by their name, but they won't show up as methods on your | ||||
| 34 | #pod class or instances. | ||||
| 35 | #pod | ||||
| 36 | #pod This module is very similar to L<namespace::clean|namespace::clean>, except it | ||||
| 37 | #pod will clean all imported functions, no matter if you imported them before or | ||||
| 38 | #pod after you C<use>d the pragma. It will also not touch anything that looks like a | ||||
| 39 | #pod method. | ||||
| 40 | #pod | ||||
| 41 | #pod If you're writing an exporter and you want to clean up after yourself (and your | ||||
| 42 | #pod peers), you can use the C<-cleanee> switch to specify what package to clean: | ||||
| 43 | #pod | ||||
| 44 | #pod package My::MooseX::namespace::autoclean; | ||||
| 45 | #pod use strict; | ||||
| 46 | #pod | ||||
| 47 | #pod use namespace::autoclean (); # no cleanup, just load | ||||
| 48 | #pod | ||||
| 49 | #pod sub import { | ||||
| 50 | #pod namespace::autoclean->import( | ||||
| 51 | #pod -cleanee => scalar(caller), | ||||
| 52 | #pod ); | ||||
| 53 | #pod } | ||||
| 54 | #pod | ||||
| 55 | #pod =head1 WHAT IS AND ISN'T CLEANED | ||||
| 56 | #pod | ||||
| 57 | #pod C<namespace::autoclean> will leave behind anything that it deems a method. For | ||||
| 58 | #pod L<Moose> classes, this the based on the C<get_method_list> method | ||||
| 59 | #pod on from the L<Class::MOP::Class|metaclass>. For non-Moose classes, anything | ||||
| 60 | #pod defined within the package will be identified as a method. This should match | ||||
| 61 | #pod Moose's definition of a method. Additionally, the magic subs installed by | ||||
| 62 | #pod L<overload> will not be cleaned. | ||||
| 63 | #pod | ||||
| 64 | #pod =head1 PARAMETERS | ||||
| 65 | #pod | ||||
| 66 | #pod =head2 -also => [ ITEM | REGEX | SUB, .. ] | ||||
| 67 | #pod | ||||
| 68 | #pod =head2 -also => ITEM | ||||
| 69 | #pod | ||||
| 70 | #pod =head2 -also => REGEX | ||||
| 71 | #pod | ||||
| 72 | #pod =head2 -also => SUB | ||||
| 73 | #pod | ||||
| 74 | #pod Sometimes you don't want to clean imports only, but also helper functions | ||||
| 75 | #pod you're using in your methods. The C<-also> switch can be used to declare a list | ||||
| 76 | #pod of functions that should be removed additional to any imports: | ||||
| 77 | #pod | ||||
| 78 | #pod use namespace::autoclean -also => ['some_function', 'another_function']; | ||||
| 79 | #pod | ||||
| 80 | #pod If only one function needs to be additionally cleaned the C<-also> switch also | ||||
| 81 | #pod accepts a plain string: | ||||
| 82 | #pod | ||||
| 83 | #pod use namespace::autoclean -also => 'some_function'; | ||||
| 84 | #pod | ||||
| 85 | #pod In some situations, you may wish for a more I<powerful> cleaning solution. | ||||
| 86 | #pod | ||||
| 87 | #pod The C<-also> switch can take a Regex or a CodeRef to match against local | ||||
| 88 | #pod function names to clean. | ||||
| 89 | #pod | ||||
| 90 | #pod use namespace::autoclean -also => qr/^_/ | ||||
| 91 | #pod | ||||
| 92 | #pod use namespace::autoclean -also => sub { $_ =~ m{^_} }; | ||||
| 93 | #pod | ||||
| 94 | #pod use namespace::autoclean -also => [qr/^_/ , qr/^hidden_/ ]; | ||||
| 95 | #pod | ||||
| 96 | #pod use namespace::autoclean -also => [sub { $_ =~ m/^_/ or $_ =~ m/^hidden/ }, sub { uc($_) == $_ } ]; | ||||
| 97 | #pod | ||||
| 98 | #pod =head2 -except => [ ITEM | REGEX | SUB, .. ] | ||||
| 99 | #pod | ||||
| 100 | #pod =head2 -except => ITEM | ||||
| 101 | #pod | ||||
| 102 | #pod =head2 -except => REGEX | ||||
| 103 | #pod | ||||
| 104 | #pod =head2 -except => SUB | ||||
| 105 | #pod | ||||
| 106 | #pod This takes exactly the same options as C<-also> except that anything this | ||||
| 107 | #pod matches will I<not> be cleaned. | ||||
| 108 | #pod | ||||
| 109 | #pod =head1 CAVEATS | ||||
| 110 | #pod | ||||
| 111 | #pod When used with L<Moo> classes, the heuristic used to check for methods won't | ||||
| 112 | #pod work correctly for methods from roles consumed at compile time. | ||||
| 113 | #pod | ||||
| 114 | #pod package My::Class; | ||||
| 115 | #pod use Moo; | ||||
| 116 | #pod use namespace::autoclean; | ||||
| 117 | #pod | ||||
| 118 | #pod # Bad, any consumed methods will be cleaned | ||||
| 119 | #pod BEGIN { with 'Some::Role' } | ||||
| 120 | #pod | ||||
| 121 | #pod # Good, methods from role will be maintained | ||||
| 122 | #pod with 'Some::Role'; | ||||
| 123 | #pod | ||||
| 124 | #pod Additionally, method detection may not work properly in L<Mouse> classes in | ||||
| 125 | #pod perls earlier than 5.10. | ||||
| 126 | #pod | ||||
| 127 | #pod =head1 SEE ALSO | ||||
| 128 | #pod | ||||
| 129 | #pod =for :list | ||||
| 130 | #pod * L<namespace::clean> | ||||
| 131 | #pod * L<B::Hooks::EndOfScope> | ||||
| 132 | #pod * L<namespace::sweep> | ||||
| 133 | #pod * L<Sub::Exporter::ForMethods> | ||||
| 134 | #pod * L<Sub::Name> | ||||
| 135 | #pod * L<Sub::Install> | ||||
| 136 | #pod * L<Test::CleanNamespaces> | ||||
| 137 | #pod * L<Dist::Zilla::Plugin::Test::CleanNamespaces> | ||||
| 138 | #pod | ||||
| 139 | #pod =cut | ||||
| 140 | |||||
| 141 | # spent 38µs (20+19) within namespace::autoclean::import which was called:
# once (20µs+19µs) by String::Markov::BEGIN@9 at line 9 of String/Markov.pm | ||||
| 142 | 1 | 1µs | my ($class, %args) = @_; | ||
| 143 | |||||
| 144 | my $subcast = sub { | ||||
| 145 | my $i = shift; | ||||
| 146 | return $i if ref $i eq 'CODE'; | ||||
| 147 | return sub { $_ =~ $i } if ref $i eq 'Regexp'; | ||||
| 148 | return sub { $_ eq $i }; | ||||
| 149 | 1 | 3µs | }; | ||
| 150 | |||||
| 151 | my $runtest = sub { | ||||
| 152 | my ($code, $method_name) = @_; | ||||
| 153 | local $_ = $method_name; | ||||
| 154 | return $code->(); | ||||
| 155 | 1 | 1µs | }; | ||
| 156 | |||||
| 157 | 1 | 2µs | my $cleanee = exists $args{-cleanee} ? $args{-cleanee} : scalar caller; | ||
| 158 | |||||
| 159 | my @also = map { $subcast->($_) } ( | ||||
| 160 | exists $args{-also} | ||||
| 161 | 1 | 1µs | ? (ref $args{-also} eq 'ARRAY' ? @{ $args{-also} } : $args{-also}) | ||
| 162 | : () | ||||
| 163 | ); | ||||
| 164 | |||||
| 165 | my @except = map { $subcast->($_) } ( | ||||
| 166 | exists $args{-except} | ||||
| 167 | 1 | 1µs | ? (ref $args{-except} eq 'ARRAY' ? @{ $args{-except} } : $args{-except}) | ||
| 168 | : () | ||||
| 169 | ); | ||||
| 170 | |||||
| 171 | # spent 2.38ms (222µs+2.16) within namespace::autoclean::__ANON__[/usr/local/share/perl/5.18.2/namespace/autoclean.pm:183] which was called:
# once (222µs+2.16ms) by B::Hooks::EndOfScope::XS::__ANON__[/usr/local/share/perl/5.18.2/B/Hooks/EndOfScope/XS.pm:17] at line 17 of B/Hooks/EndOfScope/XS.pm | ||||
| 172 | 1 | 6µs | 1 | 187µs | my $subs = namespace::clean->get_functions($cleanee); # spent 187µs making 1 call to namespace::clean::get_functions |
| 173 | 1 | 2µs | 1 | 1.24ms | my $method_check = _method_check($cleanee); # spent 1.24ms making 1 call to namespace::autoclean::_method_check |
| 174 | |||||
| 175 | 16 | 6µs | my @clean = grep { | ||
| 176 | 1 | 39µs | my $method = $_; | ||
| 177 | ! first { $runtest->($_, $method) } @except | ||||
| 178 | and ( !$method_check->($method) | ||||
| 179 | 16 | 162µs | 40 | 306µs | or first { $runtest->($_, $method) } @also) # spent 272µs making 16 calls to namespace::autoclean::__ANON__[namespace/autoclean.pm:210], avg 17µs/call
# spent 35µs making 24 calls to List::Util::first, avg 1µs/call |
| 180 | } keys %$subs; | ||||
| 181 | |||||
| 182 | 1 | 13µs | 1 | 422µs | namespace::clean->clean_subroutines($cleanee, @clean); # spent 422µs making 1 call to namespace::clean::clean_subroutines |
| 183 | 1 | 10µs | 1 | 18µs | }; # spent 18µs making 1 call to B::Hooks::EndOfScope::XS::on_scope_end |
| 184 | } | ||||
| 185 | |||||
| 186 | # spent 1.24ms (928µs+313µs) within namespace::autoclean::_method_check which was called:
# once (928µs+313µs) by namespace::autoclean::__ANON__[/usr/local/share/perl/5.18.2/namespace/autoclean.pm:183] at line 173 | ||||
| 187 | 1 | 700ns | my $package = shift; | ||
| 188 | 1 | 1µs | if ( | ||
| 189 | (defined &Class::MOP::class_of and my $meta = Class::MOP::class_of($package)) | ||||
| 190 | ) { | ||||
| 191 | my %methods = map { $_ => 1 } $meta->get_method_list; | ||||
| 192 | $methods{meta} = 1 | ||||
| 193 | if $meta->isa('Moose::Meta::Role') && Moose->VERSION < 0.90; | ||||
| 194 | return sub { $_[0] =~ /^\(/ || $methods{$_[0]} }; | ||||
| 195 | } | ||||
| 196 | else { | ||||
| 197 | 1 | 16µs | 1 | 5µs | my $does = $package->can('does') ? 'does' # spent 5µs making 1 call to UNIVERSAL::can |
| 198 | : $package->can('DOES') ? 'DOES' | ||||
| 199 | : undef; | ||||
| 200 | 1 | 95µs | require Sub::Identify; | ||
| 201 | # spent 272µs (173+99) within namespace::autoclean::__ANON__[/usr/local/share/perl/5.18.2/namespace/autoclean.pm:210] which was called 16 times, avg 17µs/call:
# 16 times (173µs+99µs) by namespace::autoclean::__ANON__[/usr/local/share/perl/5.18.2/namespace/autoclean.pm:183] at line 179, avg 17µs/call | ||||
| 202 | 16 | 44µs | 16 | 9µs | return 1 if $_[0] =~ /^\(/; # spent 9µs making 16 calls to namespace::autoclean::CORE:match, avg 544ns/call |
| 203 | 34 | 188µs | 2 | 44µs | # spent 28µs (11+17) within namespace::autoclean::BEGIN@203 which was called:
# once (11µs+17µs) by String::Markov::BEGIN@9 at line 203 # spent 28µs making 1 call to namespace::autoclean::BEGIN@203
# spent 17µs making 1 call to strict::unimport |
| 204 | 16 | 23µs | 16 | 75µs | my $code_stash = Sub::Identify::stash_name($coderef); # spent 75µs making 16 calls to Sub::Identify::stash_name, avg 5µs/call |
| 205 | 16 | 27µs | return 1 if $code_stash eq $package; | ||
| 206 | 8 | 2µs | return 1 if $code_stash eq 'constant'; | ||
| 207 | # TODO: consider if we really need this eval | ||||
| 208 | 16 | 22µs | 8 | 15µs | return 1 if $does && eval { $package->$does($code_stash) }; # spent 15µs making 8 calls to Moo::Object::does, avg 2µs/call |
| 209 | 8 | 20µs | return 0; | ||
| 210 | 1 | 11µs | }; | ||
| 211 | } | ||||
| 212 | } | ||||
| 213 | |||||
| 214 | 1 | 3µs | 1; | ||
| 215 | |||||
| 216 | 1 | 12µs | 1 | 156µs | __END__ # spent 156µs making 1 call to B::Hooks::EndOfScope::XS::__ANON__[B/Hooks/EndOfScope/XS.pm:17] |
# spent 9µs within namespace::autoclean::CORE:match which was called 16 times, avg 544ns/call:
# 16 times (9µs+0s) by namespace::autoclean::__ANON__[/usr/local/share/perl/5.18.2/namespace/autoclean.pm:210] at line 202, avg 544ns/call |