| Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Module/Pluggable/Object.pm |
| Statements | Executed 11010 statements in 19.0ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 141 | 1 | 1 | 84.2ms | 1.24s | Module::Pluggable::Object::_require |
| 5 | 1 | 1 | 7.83ms | 1.29s | Module::Pluggable::Object::search_paths |
| 1 | 1 | 1 | 7.18ms | 7.57ms | Module::Pluggable::Object::BEGIN@4 |
| 141 | 1 | 1 | 4.94ms | 1.24s | Module::Pluggable::Object::handle_finding_plugin |
| 282 | 2 | 1 | 1.75ms | 1.75ms | Module::Pluggable::Object::_is_legit |
| 1146 | 8 | 1 | 1.17ms | 1.17ms | Module::Pluggable::Object::CORE:match (opcode) |
| 159 | 2 | 1 | 957µs | 1.32ms | Module::Pluggable::Object::__ANON__[:317] |
| 141 | 1 | 1 | 876µs | 1.00ms | Module::Pluggable::Object::_is_editor_junk |
| 1 | 1 | 1 | 527µs | 1.29s | Module::Pluggable::Object::plugins |
| 1 | 1 | 1 | 487µs | 712µs | Module::Pluggable::Object::BEGIN@6 |
| 1 | 1 | 1 | 475µs | 1.30ms | Module::Pluggable::Object::BEGIN@8 |
| 300 | 2 | 1 | 417µs | 417µs | Module::Pluggable::Object::CORE:regcomp (opcode) |
| 1 | 1 | 1 | 67µs | 1.29s | Module::Pluggable::Object::search_directories |
| 1 | 1 | 1 | 50µs | 9.08ms | Module::Pluggable::Object::find_files |
| 141 | 1 | 1 | 34µs | 34µs | Module::Pluggable::Object::CORE:subst (opcode) |
| 5 | 1 | 1 | 32µs | 32µs | Module::Pluggable::Object::CORE:ftis (opcode) |
| 1 | 1 | 1 | 28µs | 28µs | Module::Pluggable::Object::CORE:sort (opcode) |
| 1 | 1 | 1 | 28µs | 44µs | Module::Pluggable::Object::BEGIN@3 |
| 1 | 1 | 1 | 13µs | 106µs | Module::Pluggable::Object::BEGIN@11 |
| 6 | 2 | 1 | 10µs | 10µs | Module::Pluggable::Object::CORE:qr (opcode) |
| 1 | 1 | 1 | 9µs | 43µs | Module::Pluggable::Object::BEGIN@5 |
| 1 | 1 | 1 | 8µs | 36µs | Module::Pluggable::Object::BEGIN@7 |
| 1 | 1 | 1 | 8µs | 8µs | Module::Pluggable::Object::handle_inc_hooks |
| 1 | 1 | 1 | 7µs | 24µs | Module::Pluggable::Object::BEGIN@9 |
| 2 | 2 | 1 | 5µs | 5µs | Module::Pluggable::Object::handle_innerpackages |
| 1 | 1 | 1 | 4µs | 4µs | Module::Pluggable::Object::_setup_exceptions |
| 1 | 1 | 1 | 4µs | 4µs | Module::Pluggable::Object::new |
| 1 | 1 | 1 | 600ns | 600ns | Module::Pluggable::Object::CORE:ftdir (opcode) |
| 0 | 0 | 0 | 0s | 0s | Module::Pluggable::Object::__ANON__[:51] |
| 0 | 0 | 0 | 0s | 0s | Module::Pluggable::Object::__ANON__[:52] |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Module::Pluggable::Object; | ||||
| 2 | |||||
| 3 | 2 | 28µs | 2 | 61µs | # spent 44µs (28+17) within Module::Pluggable::Object::BEGIN@3 which was called:
# once (28µs+17µs) by Module::Pluggable::BEGIN@5 at line 3 # spent 44µs making 1 call to Module::Pluggable::Object::BEGIN@3
# spent 17µs making 1 call to strict::import |
| 4 | 2 | 120µs | 1 | 7.57ms | # spent 7.57ms (7.18+385µs) within Module::Pluggable::Object::BEGIN@4 which was called:
# once (7.18ms+385µs) by Module::Pluggable::BEGIN@5 at line 4 # spent 7.57ms making 1 call to Module::Pluggable::Object::BEGIN@4 |
| 5 | 2 | 26µs | 2 | 77µs | # spent 43µs (9+34) within Module::Pluggable::Object::BEGIN@5 which was called:
# once (9µs+34µs) by Module::Pluggable::BEGIN@5 at line 5 # spent 43µs making 1 call to Module::Pluggable::Object::BEGIN@5
# spent 34µs making 1 call to Exporter::import |
| 6 | 2 | 89µs | 2 | 778µs | # spent 712µs (487+224) within Module::Pluggable::Object::BEGIN@6 which was called:
# once (487µs+224µs) by Module::Pluggable::BEGIN@5 at line 6 # spent 712µs making 1 call to Module::Pluggable::Object::BEGIN@6
# spent 66µs making 1 call to Exporter::import |
| 7 | 2 | 22µs | 2 | 64µs | # spent 36µs (8+28) within Module::Pluggable::Object::BEGIN@7 which was called:
# once (8µs+28µs) by Module::Pluggable::BEGIN@5 at line 7 # spent 36µs making 1 call to Module::Pluggable::Object::BEGIN@7
# spent 28µs making 1 call to Exporter::import |
| 8 | 2 | 84µs | 2 | 1.32ms | # spent 1.30ms (475µs+826µs) within Module::Pluggable::Object::BEGIN@8 which was called:
# once (475µs+826µs) by Module::Pluggable::BEGIN@5 at line 8 # spent 1.30ms making 1 call to Module::Pluggable::Object::BEGIN@8
# spent 15µs making 1 call to Exporter::import |
| 9 | 2 | 25µs | 2 | 42µs | # spent 24µs (7+18) within Module::Pluggable::Object::BEGIN@9 which was called:
# once (7µs+18µs) by Module::Pluggable::BEGIN@5 at line 9 # spent 24µs making 1 call to Module::Pluggable::Object::BEGIN@9
# spent 18µs making 1 call to vars::import |
| 10 | |||||
| 11 | 2 | 1.61ms | 2 | 108µs | # spent 106µs (13+93) within Module::Pluggable::Object::BEGIN@11 which was called:
# once (13µs+93µs) by Module::Pluggable::BEGIN@5 at line 11 # spent 106µs making 1 call to Module::Pluggable::Object::BEGIN@11
# spent 2µs making 1 call to if::import |
| 12 | |||||
| 13 | 1 | 800ns | $VERSION = '5.1'; | ||
| 14 | |||||
| 15 | |||||
| 16 | # spent 4µs within Module::Pluggable::Object::new which was called:
# once (4µs+0s) by Module::Pluggable::import at line 31 of Module/Pluggable.pm | ||||
| 17 | 1 | 300ns | my $class = shift; | ||
| 18 | 1 | 1µs | my %opts = @_; | ||
| 19 | |||||
| 20 | 1 | 4µs | return bless \%opts, $class; | ||
| 21 | |||||
| 22 | } | ||||
| 23 | |||||
| 24 | ### Eugggh, this code smells | ||||
| 25 | ### This is what happens when you keep adding patches | ||||
| 26 | ### *sigh* | ||||
| 27 | |||||
| 28 | |||||
| 29 | # spent 1.29s (527µs+1.29) within Module::Pluggable::Object::plugins which was called:
# once (527µs+1.29s) by Module::Pluggable::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Module/Pluggable.pm:32] at line 32 of Module/Pluggable.pm | ||||
| 30 | 1 | 100ns | my $self = shift; | ||
| 31 | 1 | 300ns | my @args = @_; | ||
| 32 | |||||
| 33 | # override 'require' | ||||
| 34 | 1 | 2µs | $self->{'require'} = 1 if $self->{'inner'}; | ||
| 35 | |||||
| 36 | 1 | 400ns | my $filename = $self->{'filename'}; | ||
| 37 | 1 | 100ns | my $pkg = $self->{'package'}; | ||
| 38 | |||||
| 39 | # Get the exception params instantiated | ||||
| 40 | 1 | 1µs | 1 | 4µs | $self->_setup_exceptions; # spent 4µs making 1 call to Module::Pluggable::Object::_setup_exceptions |
| 41 | |||||
| 42 | # automatically turn a scalar search path or namespace into a arrayref | ||||
| 43 | 1 | 600ns | for (qw(search_path search_dirs)) { | ||
| 44 | 2 | 2µs | $self->{$_} = [ $self->{$_} ] if exists $self->{$_} && !ref($self->{$_}); | ||
| 45 | } | ||||
| 46 | |||||
| 47 | # default search path is '<Module>::<Name>::Plugin' | ||||
| 48 | 1 | 200ns | $self->{'search_path'} ||= ["${pkg}::Plugin"]; | ||
| 49 | |||||
| 50 | # default error handler | ||||
| 51 | 1 | 2µs | $self->{'on_require_error'} ||= sub { my ($plugin, $err) = @_; carp "Couldn't require $plugin : $err"; return 0 }; | ||
| 52 | 1 | 1µs | $self->{'on_instantiate_error'} ||= sub { my ($plugin, $err) = @_; carp "Couldn't instantiate $plugin: $err"; return 0 }; | ||
| 53 | |||||
| 54 | # default whether to follow symlinks | ||||
| 55 | 1 | 400ns | $self->{'follow_symlinks'} = 1 unless exists $self->{'follow_symlinks'}; | ||
| 56 | |||||
| 57 | # check to see if we're running under test | ||||
| 58 | 1 | 2µs | my @SEARCHDIR = exists $INC{"blib.pm"} && defined $filename && $filename =~ m!(^|/)blib/! && !$self->{'force_search_all_paths'} ? grep {/blib/} @INC : @INC; | ||
| 59 | |||||
| 60 | # add any search_dir params | ||||
| 61 | 1 | 200ns | unshift @SEARCHDIR, @{$self->{'search_dirs'}} if defined $self->{'search_dirs'}; | ||
| 62 | |||||
| 63 | # set our @INC up to include and prefer our search_dirs if necessary | ||||
| 64 | 1 | 800ns | my @tmp = @INC; | ||
| 65 | 1 | 600ns | unshift @tmp, @{$self->{'search_dirs'} || []}; | ||
| 66 | 1 | 100ns | local @INC = @tmp if defined $self->{'search_dirs'}; | ||
| 67 | |||||
| 68 | 1 | 10µs | 1 | 1.29s | my @plugins = $self->search_directories(@SEARCHDIR); # spent 1.29s making 1 call to Module::Pluggable::Object::search_directories |
| 69 | 1 | 5µs | 1 | 8µs | push(@plugins, $self->handle_inc_hooks($_, @SEARCHDIR)) for @{$self->{'search_path'}}; # spent 8µs making 1 call to Module::Pluggable::Object::handle_inc_hooks |
| 70 | 1 | 2µs | 1 | 2µs | push(@plugins, $self->handle_innerpackages($_)) for @{$self->{'search_path'}}; # spent 2µs making 1 call to Module::Pluggable::Object::handle_innerpackages |
| 71 | |||||
| 72 | # return blank unless we've found anything | ||||
| 73 | 1 | 300ns | return () unless @plugins; | ||
| 74 | |||||
| 75 | # remove duplicates | ||||
| 76 | # probably not necessary but hey ho | ||||
| 77 | 1 | 100ns | my %plugins; | ||
| 78 | 1 | 600ns | for(@plugins) { | ||
| 79 | 141 | 138µs | 141 | 718µs | next unless $self->_is_legit($_); # spent 718µs making 141 calls to Module::Pluggable::Object::_is_legit, avg 5µs/call |
| 80 | 141 | 108µs | $plugins{$_} = 1; | ||
| 81 | } | ||||
| 82 | |||||
| 83 | # are we instantiating or requiring? | ||||
| 84 | 1 | 500ns | if (defined $self->{'instantiate'}) { | ||
| 85 | my $method = $self->{'instantiate'}; | ||||
| 86 | my @objs = (); | ||||
| 87 | foreach my $package (sort keys %plugins) { | ||||
| 88 | next unless $package->can($method); | ||||
| 89 | my $obj = eval { $package->$method(@_) }; | ||||
| 90 | $self->{'on_instantiate_error'}->($package, $@) if $@; | ||||
| 91 | push @objs, $obj if $obj; | ||||
| 92 | } | ||||
| 93 | return @objs; | ||||
| 94 | } else { | ||||
| 95 | # no? just return the names | ||||
| 96 | 1 | 56µs | 1 | 28µs | my @objs= sort keys %plugins; # spent 28µs making 1 call to Module::Pluggable::Object::CORE:sort |
| 97 | 1 | 42µs | return @objs; | ||
| 98 | } | ||||
| 99 | } | ||||
| 100 | |||||
| 101 | # spent 4µs within Module::Pluggable::Object::_setup_exceptions which was called:
# once (4µs+0s) by Module::Pluggable::Object::plugins at line 40 | ||||
| 102 | 1 | 200ns | my $self = shift; | ||
| 103 | |||||
| 104 | 1 | 100ns | my %only; | ||
| 105 | 1 | 0s | my %except; | ||
| 106 | 1 | 0s | my $only; | ||
| 107 | 1 | 0s | my $except; | ||
| 108 | |||||
| 109 | 1 | 200ns | if (defined $self->{'only'}) { | ||
| 110 | if (ref($self->{'only'}) eq 'ARRAY') { | ||||
| 111 | %only = map { $_ => 1 } @{$self->{'only'}}; | ||||
| 112 | } elsif (ref($self->{'only'}) eq 'Regexp') { | ||||
| 113 | $only = $self->{'only'} | ||||
| 114 | } elsif (ref($self->{'only'}) eq '') { | ||||
| 115 | $only{$self->{'only'}} = 1; | ||||
| 116 | } | ||||
| 117 | } | ||||
| 118 | |||||
| 119 | |||||
| 120 | 1 | 100ns | if (defined $self->{'except'}) { | ||
| 121 | if (ref($self->{'except'}) eq 'ARRAY') { | ||||
| 122 | %except = map { $_ => 1 } @{$self->{'except'}}; | ||||
| 123 | } elsif (ref($self->{'except'}) eq 'Regexp') { | ||||
| 124 | $except = $self->{'except'} | ||||
| 125 | } elsif (ref($self->{'except'}) eq '') { | ||||
| 126 | $except{$self->{'except'}} = 1; | ||||
| 127 | } | ||||
| 128 | } | ||||
| 129 | 1 | 800ns | $self->{_exceptions}->{only_hash} = \%only; | ||
| 130 | 1 | 300ns | $self->{_exceptions}->{only} = $only; | ||
| 131 | 1 | 300ns | $self->{_exceptions}->{except_hash} = \%except; | ||
| 132 | 1 | 4µs | $self->{_exceptions}->{except} = $except; | ||
| 133 | |||||
| 134 | } | ||||
| 135 | |||||
| 136 | sub _is_legit { | ||||
| 137 | 282 | 31µs | my $self = shift; | ||
| 138 | 282 | 30µs | my $plugin = shift; | ||
| 139 | 282 | 253µs | my %only = %{$self->{_exceptions}->{only_hash}||{}}; | ||
| 140 | 282 | 81µs | my %except = %{$self->{_exceptions}->{except_hash}||{}}; | ||
| 141 | 282 | 67µs | my $only = $self->{_exceptions}->{only}; | ||
| 142 | 282 | 38µs | my $except = $self->{_exceptions}->{except}; | ||
| 143 | 282 | 472µs | my $depth = () = split '::', $plugin, -1; | ||
| 144 | |||||
| 145 | 282 | 45µs | return 0 if (keys %only && !$only{$plugin} ); | ||
| 146 | 282 | 40µs | return 0 unless (!defined $only || $plugin =~ m!$only! ); | ||
| 147 | |||||
| 148 | 282 | 17µs | return 0 if (keys %except && $except{$plugin} ); | ||
| 149 | 282 | 22µs | return 0 if (defined $except && $plugin =~ m!$except! ); | ||
| 150 | |||||
| 151 | 282 | 45µs | return 0 if defined $self->{max_depth} && $depth>$self->{max_depth}; | ||
| 152 | 282 | 38µs | return 0 if defined $self->{min_depth} && $depth<$self->{min_depth}; | ||
| 153 | |||||
| 154 | 282 | 635µs | return 1; | ||
| 155 | } | ||||
| 156 | |||||
| 157 | # spent 1.29s (67µs+1.29) within Module::Pluggable::Object::search_directories which was called:
# once (67µs+1.29s) by Module::Pluggable::Object::plugins at line 68 | ||||
| 158 | 1 | 200ns | my $self = shift; | ||
| 159 | 1 | 900ns | my @SEARCHDIR = @_; | ||
| 160 | |||||
| 161 | 1 | 100ns | my @plugins; | ||
| 162 | # go through our @INC | ||||
| 163 | 1 | 400ns | foreach my $dir (@SEARCHDIR) { | ||
| 164 | 5 | 24µs | 5 | 1.29s | push @plugins, $self->search_paths($dir); # spent 1.29s making 5 calls to Module::Pluggable::Object::search_paths, avg 258ms/call |
| 165 | } | ||||
| 166 | 1 | 37µs | return @plugins; | ||
| 167 | } | ||||
| 168 | |||||
| 169 | |||||
| 170 | # spent 1.29s (7.83ms+1.28) within Module::Pluggable::Object::search_paths which was called 5 times, avg 258ms/call:
# 5 times (7.83ms+1.28s) by Module::Pluggable::Object::search_directories at line 164, avg 258ms/call | ||||
| 171 | 5 | 1µs | my $self = shift; | ||
| 172 | 5 | 900ns | my $dir = shift; | ||
| 173 | 5 | 300ns | my @plugins; | ||
| 174 | |||||
| 175 | 5 | 19µs | 5 | 6µs | my $file_regex = $self->{'file_regex'} || qr/\.pm$/; # spent 6µs making 5 calls to Module::Pluggable::Object::CORE:qr, avg 1µs/call |
| 176 | |||||
| 177 | |||||
| 178 | # and each directory in our search path | ||||
| 179 | 5 | 6µs | foreach my $searchpath (@{$self->{'search_path'}}) { | ||
| 180 | # create the search directory in a cross platform goodness way | ||||
| 181 | 5 | 30µs | 5 | 10µs | my $sp = catdir($dir, (split /::/, $searchpath)); # spent 10µs making 5 calls to File::Spec::Unix::_fn_catdir, avg 2µs/call |
| 182 | |||||
| 183 | # if it doesn't exist or it's not a dir then skip it | ||||
| 184 | 5 | 49µs | 6 | 32µs | next unless ( -e $sp && -d _ ); # Use the cached stat the second time # spent 32µs making 5 calls to Module::Pluggable::Object::CORE:ftis, avg 6µs/call
# spent 600ns making 1 call to Module::Pluggable::Object::CORE:ftdir |
| 185 | |||||
| 186 | 1 | 10µs | 1 | 9.08ms | my @files = $self->find_files($sp); # spent 9.08ms making 1 call to Module::Pluggable::Object::find_files |
| 187 | |||||
| 188 | # foreach one we've found | ||||
| 189 | 1 | 500ns | foreach my $file (@files) { | ||
| 190 | # untaint the file; accept .pm only | ||||
| 191 | 141 | 1.12ms | 282 | 519µs | next unless ($file) = ($file =~ /(.*$file_regex)$/); # spent 299µs making 141 calls to Module::Pluggable::Object::CORE:match, avg 2µs/call
# spent 220µs making 141 calls to Module::Pluggable::Object::CORE:regcomp, avg 2µs/call |
| 192 | # parse the file to get the name | ||||
| 193 | 141 | 258µs | 141 | 3.18ms | my ($name, $directory, $suffix) = fileparse($file, $file_regex); # spent 3.18ms making 141 calls to File::Basename::fileparse, avg 23µs/call |
| 194 | |||||
| 195 | 141 | 260µs | 141 | 1.00ms | next if (!$self->{include_editor_junk} && $self->_is_editor_junk($name)); # spent 1.00ms making 141 calls to Module::Pluggable::Object::_is_editor_junk, avg 7µs/call |
| 196 | |||||
| 197 | 141 | 229µs | 141 | 24.2ms | $directory = abs2rel($directory, $sp); # spent 24.2ms making 141 calls to File::Spec::Functions::__ANON__[File/Spec/Functions.pm:62], avg 172µs/call |
| 198 | |||||
| 199 | # If we have a mixed-case package name, assume case has been preserved | ||||
| 200 | # correctly. Otherwise, root through the file to locate the case-preserved | ||||
| 201 | # version of the package name. | ||||
| 202 | 141 | 41µs | my @pkg_dirs = (); | ||
| 203 | 141 | 110µs | if ( $name eq lc($name) || $name eq uc($name) ) { | ||
| 204 | my $pkg_file = catfile($sp, $directory, "$name$suffix"); | ||||
| 205 | open PKGFILE, "<$pkg_file" or die "search_paths: Can't open $pkg_file: $!"; | ||||
| 206 | my $in_pod = 0; | ||||
| 207 | while ( my $line = <PKGFILE> ) { | ||||
| 208 | $in_pod = 1 if $line =~ m/^=\w/; | ||||
| 209 | $in_pod = 0 if $line =~ /^=cut/; | ||||
| 210 | next if ($in_pod || $line =~ /^=cut/); # skip pod text | ||||
| 211 | next if $line =~ /^\s*#/; # and comments | ||||
| 212 | if ( $line =~ m/^\s*package\s+(.*::)?($name)\s*;/i ) { | ||||
| 213 | @pkg_dirs = split /::/, $1 if defined $1;; | ||||
| 214 | $name = $2; | ||||
| 215 | last; | ||||
| 216 | } | ||||
| 217 | } | ||||
| 218 | close PKGFILE; | ||||
| 219 | } | ||||
| 220 | |||||
| 221 | # then create the class name in a cross platform way | ||||
| 222 | 141 | 497µs | 141 | 254µs | $directory =~ s/^[a-z]://i if($^O =~ /MSWin32|dos/); # remove volume # spent 254µs making 141 calls to Module::Pluggable::Object::CORE:match, avg 2µs/call |
| 223 | 141 | 32µs | my @dirs = (); | ||
| 224 | 141 | 37µs | if ($directory) { | ||
| 225 | 141 | 512µs | 141 | 196µs | ($directory) = ($directory =~ /(.*)/); # spent 196µs making 141 calls to Module::Pluggable::Object::CORE:match, avg 1µs/call |
| 226 | 141 | 334µs | 141 | 623µs | @dirs = grep(length($_), splitdir($directory)) # spent 623µs making 141 calls to File::Spec::Functions::__ANON__[File/Spec/Functions.pm:62], avg 4µs/call |
| 227 | unless $directory eq curdir(); | ||||
| 228 | 141 | 61µs | for my $d (reverse @dirs) { | ||
| 229 | 141 | 37µs | my $pkg_dir = pop @pkg_dirs; | ||
| 230 | 141 | 90µs | last unless defined $pkg_dir; | ||
| 231 | $d =~ s/\Q$pkg_dir\E/$pkg_dir/i; # Correct case | ||||
| 232 | } | ||||
| 233 | } else { | ||||
| 234 | $directory = ""; | ||||
| 235 | } | ||||
| 236 | 141 | 99µs | my $plugin = join '::', $searchpath, @dirs, $name; | ||
| 237 | |||||
| 238 | 141 | 404µs | 141 | 155µs | next unless $plugin =~ m!(?:[a-z\d]+)[a-z\d]*!i; # spent 155µs making 141 calls to Module::Pluggable::Object::CORE:match, avg 1µs/call |
| 239 | |||||
| 240 | 141 | 386µs | 141 | 1.24s | $self->handle_finding_plugin($plugin, \@plugins) # spent 1.24s making 141 calls to Module::Pluggable::Object::handle_finding_plugin, avg 8.82ms/call |
| 241 | } | ||||
| 242 | |||||
| 243 | # now add stuff that may have been in package | ||||
| 244 | # NOTE we should probably use all the stuff we've been given already | ||||
| 245 | # but then we can't unload it :( | ||||
| 246 | 1 | 29µs | 1 | 3µs | push @plugins, $self->handle_innerpackages($searchpath); # spent 3µs making 1 call to Module::Pluggable::Object::handle_innerpackages |
| 247 | } # foreach $searchpath | ||||
| 248 | |||||
| 249 | 5 | 74µs | return @plugins; | ||
| 250 | } | ||||
| 251 | |||||
| 252 | # spent 1.00ms (876µs+127µs) within Module::Pluggable::Object::_is_editor_junk which was called 141 times, avg 7µs/call:
# 141 times (876µs+127µs) by Module::Pluggable::Object::search_paths at line 195, avg 7µs/call | ||||
| 253 | 141 | 31µs | my $self = shift; | ||
| 254 | 141 | 20µs | my $name = shift; | ||
| 255 | |||||
| 256 | # Emacs (and other Unix-y editors) leave temp files ending in a | ||||
| 257 | # tilde as a backup. | ||||
| 258 | 141 | 297µs | 141 | 55µs | return 1 if $name =~ /~$/; # spent 55µs making 141 calls to Module::Pluggable::Object::CORE:match, avg 390ns/call |
| 259 | # Emacs makes these files while a buffer is edited but not yet | ||||
| 260 | # saved. | ||||
| 261 | 141 | 203µs | 141 | 30µs | return 1 if $name =~ /^\.#/; # spent 30µs making 141 calls to Module::Pluggable::Object::CORE:match, avg 213ns/call |
| 262 | # Vim can leave these files behind if it crashes. | ||||
| 263 | 141 | 202µs | 141 | 42µs | return 1 if $name =~ /\.sw[po]$/; # spent 42µs making 141 calls to Module::Pluggable::Object::CORE:match, avg 298ns/call |
| 264 | |||||
| 265 | 141 | 275µs | return 0; | ||
| 266 | } | ||||
| 267 | |||||
| 268 | # spent 1.24s (4.94ms+1.24) within Module::Pluggable::Object::handle_finding_plugin which was called 141 times, avg 8.82ms/call:
# 141 times (4.94ms+1.24s) by Module::Pluggable::Object::search_paths at line 240, avg 8.82ms/call | ||||
| 269 | 141 | 32µs | my $self = shift; | ||
| 270 | 141 | 17µs | my $plugin = shift; | ||
| 271 | 141 | 15µs | my $plugins = shift; | ||
| 272 | 141 | 29µs | my $no_req = shift || 0; | ||
| 273 | |||||
| 274 | 141 | 136µs | 141 | 1.04ms | return unless $self->_is_legit($plugin); # spent 1.04ms making 141 calls to Module::Pluggable::Object::_is_legit, avg 7µs/call |
| 275 | 141 | 53µs | unless (defined $self->{'instantiate'} || $self->{'require'}) { | ||
| 276 | push @$plugins, $plugin; | ||||
| 277 | return; | ||||
| 278 | } | ||||
| 279 | |||||
| 280 | 141 | 17µs | $self->{before_require}->($plugin) || return if defined $self->{before_require}; | ||
| 281 | 141 | 19µs | unless ($no_req) { | ||
| 282 | 141 | 29µs | my $tmp = $@; | ||
| 283 | 282 | 232µs | 141 | 1.24s | my $res = eval { $self->_require($plugin) }; # spent 1.24s making 141 calls to Module::Pluggable::Object::_require, avg 8.78ms/call |
| 284 | 141 | 27µs | my $err = $@; | ||
| 285 | 141 | 16µs | $@ = $tmp; | ||
| 286 | 141 | 31µs | if ($err) { | ||
| 287 | if (defined $self->{on_require_error}) { | ||||
| 288 | $self->{on_require_error}->($plugin, $err) || return; | ||||
| 289 | } else { | ||||
| 290 | return; | ||||
| 291 | } | ||||
| 292 | } | ||||
| 293 | } | ||||
| 294 | 141 | 61µs | $self->{after_require}->($plugin) || return if defined $self->{after_require}; | ||
| 295 | 141 | 386µs | push @$plugins, $plugin; | ||
| 296 | } | ||||
| 297 | |||||
| 298 | # spent 9.08ms (50µs+9.03) within Module::Pluggable::Object::find_files which was called:
# once (50µs+9.03ms) by Module::Pluggable::Object::search_paths at line 186 | ||||
| 299 | 1 | 200ns | my $self = shift; | ||
| 300 | 1 | 200ns | my $search_path = shift; | ||
| 301 | 1 | 7µs | 1 | 4µs | my $file_regex = $self->{'file_regex'} || qr/\.pm$/; # spent 4µs making 1 call to Module::Pluggable::Object::CORE:qr |
| 302 | |||||
| 303 | |||||
| 304 | # find all the .pm files in it | ||||
| 305 | # this isn't perfect and won't find multiple plugins per file | ||||
| 306 | #my $cwd = Cwd::getcwd; | ||||
| 307 | 1 | 300ns | my @files = (); | ||
| 308 | { # for the benefit of perl 5.6.1's Find, localize topic | ||||
| 309 | 2 | 3µs | local $_; | ||
| 310 | File::Find::find( { no_chdir => 1, | ||||
| 311 | follow => $self->{'follow_symlinks'}, | ||||
| 312 | # spent 1.32ms (957µs+367µs) within Module::Pluggable::Object::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Module/Pluggable/Object.pm:317] which was called 159 times, avg 8µs/call:
# 141 times (880µs+344µs) by File::Find::_find_dir_symlnk at line 1012 of File/Find.pm, avg 9µs/call
# 18 times (77µs+23µs) by File::Find::_find_dir_symlnk at line 933 of File/Find.pm, avg 6µs/call | ||||
| 313 | # Inlined from File::Find::Rule C< name => '*.pm' > | ||||
| 314 | 159 | 832µs | 318 | 332µs | return unless $File::Find::name =~ /$file_regex/; # spent 197µs making 159 calls to Module::Pluggable::Object::CORE:regcomp, avg 1µs/call
# spent 135µs making 159 calls to Module::Pluggable::Object::CORE:match, avg 849ns/call |
| 315 | 141 | 252µs | 141 | 34µs | (my $path = $File::Find::name) =~ s#^\\./##; # spent 34µs making 141 calls to Module::Pluggable::Object::CORE:subst, avg 245ns/call |
| 316 | 141 | 314µs | push @files, $path; | ||
| 317 | } | ||||
| 318 | 1 | 4µs | 1 | 9.03ms | }, $search_path ); # spent 9.03ms making 1 call to File::Find::find |
| 319 | } | ||||
| 320 | #chdir $cwd; | ||||
| 321 | 1 | 40µs | return @files; | ||
| 322 | |||||
| 323 | } | ||||
| 324 | |||||
| 325 | # spent 8µs within Module::Pluggable::Object::handle_inc_hooks which was called:
# once (8µs+0s) by Module::Pluggable::Object::plugins at line 69 | ||||
| 326 | 1 | 400ns | my $self = shift; | ||
| 327 | 1 | 500ns | my $path = shift; | ||
| 328 | 1 | 2µs | my @SEARCHDIR = @_; | ||
| 329 | |||||
| 330 | 1 | 100ns | my @plugins; | ||
| 331 | 1 | 1µs | for my $dir ( @SEARCHDIR ) { | ||
| 332 | 5 | 400ns | next unless ref $dir && eval { $dir->can( 'files' ) }; | ||
| 333 | |||||
| 334 | foreach my $plugin ( $dir->files ) { | ||||
| 335 | $plugin =~ s/\.pm$//; | ||||
| 336 | $plugin =~ s{/}{::}g; | ||||
| 337 | next unless $plugin =~ m!^${path}::!; | ||||
| 338 | $self->handle_finding_plugin( $plugin, \@plugins ); | ||||
| 339 | } | ||||
| 340 | } | ||||
| 341 | 1 | 4µs | return @plugins; | ||
| 342 | } | ||||
| 343 | |||||
| 344 | sub handle_innerpackages { | ||||
| 345 | 2 | 600ns | my $self = shift; | ||
| 346 | 2 | 8µs | return () if (exists $self->{inner} && !$self->{inner}); | ||
| 347 | |||||
| 348 | my $path = shift; | ||||
| 349 | my @plugins; | ||||
| 350 | |||||
| 351 | foreach my $plugin (Devel::InnerPackage::list_packages($path)) { | ||||
| 352 | $self->handle_finding_plugin($plugin, \@plugins, 1); | ||||
| 353 | } | ||||
| 354 | return @plugins; | ||||
| 355 | |||||
| 356 | } | ||||
| 357 | |||||
| 358 | |||||
| 359 | # spent 1.24s (84.2ms+1.15) within Module::Pluggable::Object::_require which was called 141 times, avg 8.78ms/call:
# 141 times (84.2ms+1.15s) by Module::Pluggable::Object::handle_finding_plugin at line 283, avg 8.78ms/call | ||||
| 360 | 141 | 26µs | my $self = shift; | ||
| 361 | 141 | 16µs | my $pack = shift; | ||
| 362 | 141 | 2.61ms | eval "CORE::require $pack"; # spent 177µs executing statements in 2 string evals (merged)
# spent 125µs executing statements in string eval
# spent 107µs executing statements in string eval
# spent 105µs executing statements in string eval
# spent 102µs executing statements in string eval
# spent 91µs executing statements in string eval
# spent 91µs executing statements in string eval
# spent 90µs executing statements in string eval
# spent 90µs executing statements in string eval
# spent 89µs executing statements in string eval
# spent 88µs executing statements in string eval
# spent 87µs executing statements in string eval
# spent 83µs executing statements in string eval
# spent 78µs executing statements in string eval
# spent 77µs executing statements in string eval
# spent 76µs executing statements in string eval
# spent 76µs executing statements in string eval
# spent 75µs executing statements in string eval
# spent 75µs executing statements in string eval
# spent 75µs executing statements in string eval
# spent 74µs executing statements in string eval
# spent 73µs executing statements in string eval
# spent 73µs executing statements in string eval
# spent 72µs executing statements in string eval
# spent 72µs executing statements in string eval
# spent 72µs executing statements in string eval
# spent 72µs executing statements in string eval
# spent 72µs executing statements in string eval
# spent 72µs executing statements in string eval
# spent 72µs executing statements in string eval
# spent 71µs executing statements in string eval
# spent 71µs executing statements in string eval
# spent 71µs executing statements in string eval
# spent 71µs executing statements in string eval
# spent 71µs executing statements in string eval
# spent 71µs executing statements in string eval
# spent 71µs executing statements in string eval
# spent 71µs executing statements in string eval
# spent 71µs executing statements in string eval
# spent 71µs executing statements in string eval
# spent 71µs executing statements in string eval
# spent 70µs executing statements in string eval
# spent 70µs executing statements in string eval
# spent 70µs executing statements in string eval
# spent 70µs executing statements in string eval
# spent 70µs executing statements in string eval
# spent 70µs executing statements in string eval
# spent 70µs executing statements in string eval
# spent 70µs executing statements in string eval
# spent 69µs executing statements in string eval
# spent 69µs executing statements in string eval
# spent 69µs executing statements in string eval
# spent 69µs executing statements in string eval
# spent 69µs executing statements in string eval
# spent 69µs executing statements in string eval
# spent 69µs executing statements in string eval
# spent 69µs executing statements in string eval
# spent 69µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 68µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 67µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 66µs executing statements in string eval
# spent 65µs executing statements in string eval
# spent 65µs executing statements in string eval
# spent 65µs executing statements in string eval
# spent 65µs executing statements in string eval
# spent 65µs executing statements in string eval
# spent 65µs executing statements in string eval
# spent 65µs executing statements in string eval
# spent 65µs executing statements in string eval
# spent 65µs executing statements in string eval
# spent 65µs executing statements in string eval
# spent 65µs executing statements in string eval
# spent 64µs executing statements in string eval
# spent 64µs executing statements in string eval
# spent 64µs executing statements in string eval
# spent 64µs executing statements in string eval
# spent 64µs executing statements in string eval
# spent 64µs executing statements in string eval
# spent 64µs executing statements in string eval
# spent 64µs executing statements in string eval
# spent 63µs executing statements in string eval
# spent 63µs executing statements in string eval
# spent 63µs executing statements in string eval
# spent 63µs executing statements in string eval
# spent 63µs executing statements in string eval
# spent 63µs executing statements in string eval
# spent 63µs executing statements in string eval
# spent 63µs executing statements in string eval
# spent 62µs executing statements in string eval
# spent 62µs executing statements in string eval
# spent 62µs executing statements in string eval
# spent 62µs executing statements in string eval
# spent 62µs executing statements in string eval
# spent 62µs executing statements in string eval
# spent 62µs executing statements in string eval
# spent 62µs executing statements in string eval
# spent 62µs executing statements in string eval
# spent 62µs executing statements in string eval | ||
| 363 | 141 | 15µs | die ($@) if $@; | ||
| 364 | 141 | 3.73ms | return 1; | ||
| 365 | } | ||||
| 366 | |||||
| 367 | |||||
| 368 | 1 | 2µs | 1; | ||
| 369 | |||||
| 370 | =pod | ||||
| 371 | |||||
| 372 | =head1 NAME | ||||
| 373 | |||||
| 374 | Module::Pluggable::Object - automatically give your module the ability to have plugins | ||||
| 375 | |||||
| 376 | =head1 SYNOPSIS | ||||
| 377 | |||||
| 378 | |||||
| 379 | Simple use Module::Pluggable - | ||||
| 380 | |||||
| 381 | package MyClass; | ||||
| 382 | use Module::Pluggable::Object; | ||||
| 383 | |||||
| 384 | my $finder = Module::Pluggable::Object->new(%opts); | ||||
| 385 | print "My plugins are: ".join(", ", $finder->plugins)."\n"; | ||||
| 386 | |||||
| 387 | =head1 DESCRIPTION | ||||
| 388 | |||||
| 389 | Provides a simple but, hopefully, extensible way of having 'plugins' for | ||||
| 390 | your module. Obviously this isn't going to be the be all and end all of | ||||
| 391 | solutions but it works for me. | ||||
| 392 | |||||
| 393 | Essentially all it does is export a method into your namespace that | ||||
| 394 | looks through a search path for .pm files and turn those into class names. | ||||
| 395 | |||||
| 396 | Optionally it instantiates those classes for you. | ||||
| 397 | |||||
| 398 | This object is wrapped by C<Module::Pluggable>. If you want to do something | ||||
| 399 | odd or add non-general special features you're probably best to wrap this | ||||
| 400 | and produce your own subclass. | ||||
| 401 | |||||
| 402 | =head1 OPTIONS | ||||
| 403 | |||||
| 404 | See the C<Module::Pluggable> docs. | ||||
| 405 | |||||
| 406 | =head1 AUTHOR | ||||
| 407 | |||||
| 408 | Simon Wistow <simon@thegestalt.org> | ||||
| 409 | |||||
| 410 | =head1 COPYING | ||||
| 411 | |||||
| 412 | Copyright, 2006 Simon Wistow | ||||
| 413 | |||||
| 414 | Distributed under the same terms as Perl itself. | ||||
| 415 | |||||
| 416 | =head1 BUGS | ||||
| 417 | |||||
| 418 | None known. | ||||
| 419 | |||||
| 420 | =head1 SEE ALSO | ||||
| 421 | |||||
| 422 | L<Module::Pluggable> | ||||
| 423 | |||||
| 424 | =cut | ||||
| 425 | |||||
# spent 600ns within Module::Pluggable::Object::CORE:ftdir which was called:
# once (600ns+0s) by Module::Pluggable::Object::search_paths at line 184 | |||||
# spent 32µs within Module::Pluggable::Object::CORE:ftis which was called 5 times, avg 6µs/call:
# 5 times (32µs+0s) by Module::Pluggable::Object::search_paths at line 184, avg 6µs/call | |||||
# spent 1.17ms within Module::Pluggable::Object::CORE:match which was called 1146 times, avg 1µs/call:
# 159 times (135µs+0s) by Module::Pluggable::Object::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Module/Pluggable/Object.pm:317] at line 314, avg 849ns/call
# 141 times (299µs+0s) by Module::Pluggable::Object::search_paths at line 191, avg 2µs/call
# 141 times (254µs+0s) by Module::Pluggable::Object::search_paths at line 222, avg 2µs/call
# 141 times (196µs+0s) by Module::Pluggable::Object::search_paths at line 225, avg 1µs/call
# 141 times (155µs+0s) by Module::Pluggable::Object::search_paths at line 238, avg 1µs/call
# 141 times (55µs+0s) by Module::Pluggable::Object::_is_editor_junk at line 258, avg 390ns/call
# 141 times (42µs+0s) by Module::Pluggable::Object::_is_editor_junk at line 263, avg 298ns/call
# 141 times (30µs+0s) by Module::Pluggable::Object::_is_editor_junk at line 261, avg 213ns/call | |||||
sub Module::Pluggable::Object::CORE:qr; # opcode | |||||
# spent 417µs within Module::Pluggable::Object::CORE:regcomp which was called 300 times, avg 1µs/call:
# 159 times (197µs+0s) by Module::Pluggable::Object::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Module/Pluggable/Object.pm:317] at line 314, avg 1µs/call
# 141 times (220µs+0s) by Module::Pluggable::Object::search_paths at line 191, avg 2µs/call | |||||
# spent 28µs within Module::Pluggable::Object::CORE:sort which was called:
# once (28µs+0s) by Module::Pluggable::Object::plugins at line 96 | |||||
# spent 34µs within Module::Pluggable::Object::CORE:subst which was called 141 times, avg 245ns/call:
# 141 times (34µs+0s) by Module::Pluggable::Object::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Module/Pluggable/Object.pm:317] at line 315, avg 245ns/call |