← Index
NYTProf Performance Profile   « line view »
For examples/Atom-timer.pl
  Run on Mon Aug 12 14:45:28 2013
Reported on Mon Aug 12 14:46:14 2013

Filename/Users/dde/perl5/perlbrew/perls/5.18.0t/lib/site_perl/5.18.0/Class/Load.pm
StatementsExecuted 3710 statements in 8.44ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
321215.99ms162msClass::Load::::try_load_classClass::Load::try_load_class (recurses: max depth 3, inclusive time 70.8ms)
32012101.07ms162msClass::Load::::load_classClass::Load::load_class (recurses: max depth 3, inclusive time 70.9ms)
111805µs895µsClass::Load::::BEGIN@7Class::Load::BEGIN@7
111738µs4.67msClass::Load::::BEGIN@9Class::Load::BEGIN@9
111567µs5.29msClass::Load::::BEGIN@8Class::Load::BEGIN@8
21149µs299µsClass::Load::::load_first_existing_classClass::Load::load_first_existing_class
11110µs38µsClass::Load::::BEGIN@10Class::Load::BEGIN@10
11110µs20µsClass::Load::::BEGIN@5Class::Load::BEGIN@5
1118µs12µsClass::Load::::_errorClass::Load::_error
1118µs8µsClass::Load::::CORE:regcompClass::Load::CORE:regcomp (opcode)
1116µs31µsClass::Load::::BEGIN@16Class::Load::BEGIN@16
1116µs9µsClass::Load::::BEGIN@6Class::Load::BEGIN@6
1114µs4µsClass::Load::::CORE:substClass::Load::CORE:subst (opcode)
111800ns800nsClass::Load::::CORE:matchClass::Load::CORE:match (opcode)
0000s0sClass::Load::::__ANON__[:152]Class::Load::__ANON__[:152]
0000s0sClass::Load::::__ANON__[:155]Class::Load::__ANON__[:155]
0000s0sClass::Load::::__ANON__[:180]Class::Load::__ANON__[:180]
0000s0sClass::Load::::__ANON__[:183]Class::Load::__ANON__[:183]
0000s0sClass::Load::::_croakClass::Load::_croak
0000s0sClass::Load::::_nonexistent_fail_reClass::Load::_nonexistent_fail_re
0000s0sClass::Load::::_or_listClass::Load::_or_list
0000s0sClass::Load::::_version_fail_reClass::Load::_version_fail_re
0000s0sClass::Load::::load_optional_classClass::Load::load_optional_class
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Class::Load;
2{
32800ns $Class::Load::VERSION = '0.20';
4}
5219µs230µs
# spent 20µs (10+10) within Class::Load::BEGIN@5 which was called: # once (10µs+10µs) by Moose::BEGIN@15 at line 5
use strict;
# spent 20µs making 1 call to Class::Load::BEGIN@5 # spent 10µs making 1 call to strict::import
6218µs212µs
# spent 9µs (6+3) within Class::Load::BEGIN@6 which was called: # once (6µs+3µs) by Moose::BEGIN@15 at line 6
use warnings;
# spent 9µs making 1 call to Class::Load::BEGIN@6 # spent 3µs making 1 call to warnings::import
7284µs2948µs
# spent 895µs (805+90) within Class::Load::BEGIN@7 which was called: # once (805µs+90µs) by Moose::BEGIN@15 at line 7
use base 'Exporter';
# spent 895µs making 1 call to Class::Load::BEGIN@7 # spent 53µs making 1 call to base::import
8279µs25.35ms
# spent 5.29ms (567µs+4.72) within Class::Load::BEGIN@8 which was called: # once (567µs+4.72ms) by Moose::BEGIN@15 at line 8
use Data::OptList 'mkopt';
# spent 5.29ms making 1 call to Class::Load::BEGIN@8 # spent 62µs making 1 call to Sub::Install::__ANON__[Sub/Install.pm:284]
93123µs24.68ms
# spent 4.67ms (738µs+3.93) within Class::Load::BEGIN@9 which was called: # once (738µs+3.93ms) by Moose::BEGIN@15 at line 9
use Module::Implementation 0.04;
# spent 4.67ms making 1 call to Class::Load::BEGIN@9 # spent 8µs making 1 call to UNIVERSAL::VERSION
101200ns
# spent 38µs (10+29) within Class::Load::BEGIN@10 which was called: # once (10µs+29µs) by Moose::BEGIN@15 at line 15
use Module::Runtime 0.012 qw(
11 check_module_name
12 module_notional_filename
13 require_module
14 use_module
15232µs367µs);
# spent 38µs making 1 call to Class::Load::BEGIN@10 # spent 22µs making 1 call to Module::Runtime::import # spent 7µs making 1 call to UNIVERSAL::VERSION
162822µs256µs
# spent 31µs (6+25) within Class::Load::BEGIN@16 which was called: # once (6µs+25µs) by Moose::BEGIN@15 at line 16
use Try::Tiny;
# spent 31µs making 1 call to Class::Load::BEGIN@16 # spent 25µs making 1 call to Exporter::import
17
18{
1923µs124µs my $loader = Module::Implementation::build_loader_sub(
# spent 24µs making 1 call to Module::Implementation::build_loader_sub
20 implementations => [ 'XS', 'PP' ],
21 symbols => ['is_class_loaded'],
22 );
23
2414µs1542µs $loader->();
25}
26
2711µsour @EXPORT_OK = qw/load_class load_optional_class try_load_class is_class_loaded load_first_existing_class/;
281700nsour %EXPORT_TAGS = (
29 all => \@EXPORT_OK,
30);
31
3210sour $ERROR;
33
34
# spent 162ms (1.07+161) within Class::Load::load_class which was called 320 times, avg 508µs/call: # 148 times (443µs+10.4ms) by Moose::Meta::Class::_inline_create_error at line 843 of Moose/Meta/Class.pm, avg 73µs/call # 52 times (189µs+90.9ms) by Moose::Meta::Attribute::Native::Trait::_native_accessor_class_for at line 204 of Moose/Meta/Attribute/Native/Trait.pm, avg 1.75ms/call # 31 times (93µs+560µs) by Class::MOP::Class::_inline_constructor at line 1436 of Class/MOP/Class.pm, avg 21µs/call # 26 times (119µs+17.4ms) by Moose::Util::_apply_all_roles at line 132 of Moose/Util.pm, avg 674µs/call # 21 times (60µs+124µs) by Moose::Meta::Role::apply at line 459 of Moose/Meta/Role.pm, avg 9µs/call # 20 times (62µs+295µs) by Moose::Meta::Class::superclasses at line 564 of Moose/Meta/Class.pm, avg 18µs/call # 14 times (62µs+1.61ms) by Class::MOP::MiniTrait::apply at line 18 of Class/MOP/MiniTrait.pm, avg 119µs/call # 3 times (9µs+12µs) by Moose::Meta::Role::Composite::apply_params at line 130 of Moose/Meta/Role/Composite.pm, avg 7µs/call # 2 times (15µs+27.5ms) by MooseX::Storage::_expand_role at line 77 of Class/MOP.pm, avg 13.8ms/call # once (7µs+12.5ms) by Moose::Meta::Attribute::Custom::Trait::Array::register_implementation at line 28 of Moose/Meta/Attribute/Native.pm # once (3µs+18µs) by metaclass::import at line 32 of metaclass.pm # once (3µs+18µs) by Class::MOP::Class::_inline_destructor at line 1473 of Class/MOP/Class.pm
sub load_class {
3532044µs my $class = shift;
3632032µs my $options = shift;
37
38320325µs320161ms my ($res, $e) = try_load_class($class, $options);
# spent 232ms making 320 calls to Class::Load::try_load_class, avg 726µs/call, recursion: max depth 3, sum of overlapping time 70.8ms
39320430µs return $class if $res;
40
41 _croak($e);
42}
43
44
# spent 299µs (49+250) within Class::Load::load_first_existing_class which was called 2 times, avg 150µs/call: # 2 times (49µs+250µs) by Moose::Util::resolve_metaclass_alias at line 225 of Moose/Util.pm, avg 150µs/call
sub load_first_existing_class {
4522µs232µs my $classes = Data::OptList::mkopt(\@_)
# spent 32µs making 2 calls to Data::OptList::mkopt, avg 16µs/call
46 or return;
47
4821µs foreach my $class (@{$classes}) {
4946µs438µs check_module_name($class->[0]);
# spent 38µs making 4 calls to Module::Runtime::check_module_name, avg 9µs/call
50 }
51
5221µs for my $class (@{$classes}) {
5332µs my ($name, $options) = @{$class};
54
55 # We need to be careful not to pass an undef $options to this sub,
56 # since the XS version will blow up if that happens.
57325µs312µs return $name if is_class_loaded($name, ($options ? $options : ()));
# spent 12µs making 3 calls to Class::Load::XS::is_class_loaded, avg 4µs/call
58
5915µs1142µs my ($res, $e) = try_load_class($name, $options);
# spent 142µs making 1 call to Class::Load::try_load_class
60
611200ns return $name if $res;
62
6311µs117µs my $file = module_notional_filename($name);
# spent 17µs making 1 call to Module::Runtime::module_notional_filename
64
65117µs29µs next if $e =~ /^Can't locate \Q$file\E in \@INC/;
# spent 8µs making 1 call to Class::Load::CORE:regcomp # spent 800ns making 1 call to Class::Load::CORE:match
66 next
67 if $options
68 && defined $options->{-version}
69 && $e =~ _version_fail_re($name, $options->{-version});
70
71 _croak("Couldn't load class ($name) because: $e");
72 }
73
74 my @list = map {
75 $_->[0]
76 . ( $_->[1] && defined $_->[1]{-version}
77 ? " (version >= $_->[1]{-version})"
78 : q{} )
79 } @{$classes};
80
81 my $err
82 .= q{Can't locate }
83 . _or_list(@list)
84 . " in \@INC (\@INC contains: @INC).";
85 _croak($err);
86}
87
88sub _version_fail_re {
89 my $name = shift;
90 my $vers = shift;
91
92 return qr/\Q$name\E version \Q$vers\E required--this is only version/;
93}
94
95sub _nonexistent_fail_re {
96 my $name = shift;
97
98 my $file = module_notional_filename($name);
99 return qr/Can't locate \Q$file\E in \@INC/;
100}
101
102sub _or_list {
103 return $_[0] if @_ == 1;
104
105 return join ' or ', @_ if @_ ==2;
106
107 my $last = pop;
108
109 my $list = join ', ', @_;
110 $list .= ', or ' . $last;
111
112 return $list;
113}
114
115sub load_optional_class {
116 my $class = shift;
117 my $options = shift;
118
119 check_module_name($class);
120
121 my ($res, $e) = try_load_class($class, $options);
122 return 1 if $res;
123
124 return 0
125 if $options
126 && defined $options->{-version}
127 && $e =~ _version_fail_re($class, $options->{-version});
128
129 return 0
130 if $e =~ _nonexistent_fail_re($class);
131
132 _croak($e);
133}
134
135
# spent 162ms (5.99+156) within Class::Load::try_load_class which was called 321 times, avg 503µs/call: # 320 times (5.98ms+155ms) by Class::Load::load_class at line 38, avg 505µs/call # once (13µs+130µs) by Class::Load::load_first_existing_class at line 59
sub try_load_class {
13632141µs my $class = shift;
1373212µs my $options = shift;
138
139321283µs3217.15ms check_module_name($class);
# spent 7.15ms making 321 calls to Module::Runtime::check_module_name, avg 22µs/call
140
14132131µs local $@;
14232133µs undef $ERROR;
143
1443215.15ms321532µs if (is_class_loaded($class)) {
# spent 532µs making 321 calls to Class::Load::XS::is_class_loaded, avg 2µs/call
145 # We need to check this here rather than in is_class_loaded() because
146 # we want to return the error message for a failed version check, but
147 # is_class_loaded just returns true/false.
148299488µs return 1 unless $options && defined $options->{-version};
149 return try {
150 $class->VERSION($options->{-version});
151 1;
152 }
153 catch {
154 _error($_);
155 };
156 }
157
1582225µs22357µs my $file = module_notional_filename($class);
# spent 357µs making 22 calls to Module::Runtime::module_notional_filename, avg 16µs/call
159 # This says "our diagnostics of the package
160 # say perl's INC status about the file being loaded are
161 # wrong", so we delete it from %INC, so when we call require(),
162 # perl will *actually* try reloading the file.
163 #
164 # If the file is already in %INC, it won't retry,
165 # And on 5.8, it won't fail either!
166 #
167 # The extra benefit of this trick, is it helps even on
168 # 5.10, as instead of dying with "Compilation failed",
169 # it will die with the actual error, and thats a win-win.
1702213µs delete $INC{$file};
171 return try {
1722239µs local $SIG{__DIE__} = 'DEFAULT';
1732219µs if ($options && defined $options->{-version}) {
174 use_module($class, $options->{-version});
175 }
176 else {
1772219µs22148ms require_module($class);
# spent 218ms making 22 calls to Module::Runtime::require_module, avg 9.90ms/call, recursion: max depth 3, sum of overlapping time 69.9ms
178 }
1792156µs 1;
180 }
181 catch {
18214µs112µs _error($_);
# spent 12µs making 1 call to Class::Load::_error
18322146µs4458.4ms };
# spent 218ms making 22 calls to Try::Tiny::try, avg 9.92ms/call, recursion: max depth 4, sum of overlapping time 160ms # spent 64µs making 22 calls to Try::Tiny::catch, avg 3µs/call
184}
185
186
# spent 12µs (8+4) within Class::Load::_error which was called: # once (8µs+4µs) by Class::Load::catch {...} at line 182
sub _error {
1871500ns my $e = shift;
188
18918µs14µs $e =~ s/ at .+?Runtime\.pm line [0-9]+\.$//;
# spent 4µs making 1 call to Class::Load::CORE:subst
1901700ns chomp $e;
191
1921500ns $ERROR = $e;
1931200ns return 0 unless wantarray;
19413µs return 0, $ERROR;
195}
196
197sub _croak {
198 require Carp;
199 local $Carp::CarpLevel = $Carp::CarpLevel + 2;
200 Carp::croak(shift);
201}
202
20315µs1;
204
205# ABSTRACT: a working (require "Class::Name") and more
206
- -
209=pod
210
211=head1 NAME
212
213Class::Load - a working (require "Class::Name") and more
214
215=head1 VERSION
216
217version 0.20
218
219=head1 SYNOPSIS
220
221 use Class::Load ':all';
222
223 try_load_class('Class::Name')
224 or plan skip_all => "Class::Name required to run these tests";
225
226 load_class('Class::Name');
227
228 is_class_loaded('Class::Name');
229
230 my $baseclass = load_optional_class('Class::Name::MightExist')
231 ? 'Class::Name::MightExist'
232 : 'Class::Name::Default';
233
234=head1 DESCRIPTION
235
236C<require EXPR> only accepts C<Class/Name.pm> style module names, not
237C<Class::Name>. How frustrating! For that, we provide
238C<load_class 'Class::Name'>.
239
240It's often useful to test whether a module can be loaded, instead of throwing
241an error when it's not available. For that, we provide
242C<try_load_class 'Class::Name'>.
243
244Finally, sometimes we need to know whether a particular class has been loaded.
245Asking C<%INC> is an option, but that will miss inner packages and any class
246for which the filename does not correspond to the package name. For that, we
247provide C<is_class_loaded 'Class::Name'>.
248
249=head1 FUNCTIONS
250
251=head2 load_class Class::Name, \%options
252
253C<load_class> will load C<Class::Name> or throw an error, much like C<require>.
254
255If C<Class::Name> is already loaded (checked with C<is_class_loaded>) then it
256will not try to load the class. This is useful when you have inner packages
257which C<require> does not check.
258
259The C<%options> hash currently accepts one key, C<-version>. If you specify a
260version, then this subroutine will call C<< Class::Name->VERSION(
261$options{-version} ) >> internally, which will throw an error if the class's
262version is not equal to or greater than the version you requested.
263
264This method will return the name of the class on success.
265
266=head2 try_load_class Class::Name, \%options -> (0|1, error message)
267
268Returns 1 if the class was loaded, 0 if it was not. If the class was not
269loaded, the error will be returned as a second return value in list context.
270
271Again, if C<Class::Name> is already loaded (checked with C<is_class_loaded>)
272then it will not try to load the class. This is useful when you have inner
273packages which C<require> does not check.
274
275Like C<load_class>, you can pass a C<-version> in C<%options>. If the version
276is not sufficient, then this subroutine will return false.
277
278=head2 is_class_loaded Class::Name, \%options -> 0|1
279
280This uses a number of heuristics to determine if the class C<Class::Name> is
281loaded. There heuristics were taken from L<Class::MOP>'s old pure-perl
282implementation.
283
284Like C<load_class>, you can pass a C<-version> in C<%options>. If the version
285is not sufficient, then this subroutine will return false.
286
287=head2 load_first_existing_class Class::Name, \%options, ...
288
289This attempts to load the first loadable class in the list of classes
290given. Each class name can be followed by an options hash reference.
291
292If any one of the classes loads and passes the optional version check, that
293class name will be returned. If I<none> of the classes can be loaded (or none
294pass their version check), then an error will be thrown.
295
296If, when attempting to load a class, it fails to load because of a syntax
297error, then an error will be thrown immediately.
298
299=head2 load_optional_class Class::Name, \%options -> 0|1
300
301C<load_optional_class> is a lot like C<try_load_class>, but also a lot like
302C<load_class>.
303
304If the class exists, and it works, then it will return 1. If you specify a
305version in C<%options>, then the version check must succeed or it will return
3060.
307
308If the class doesn't exist, and it appears to not exist on disk either, it
309will return 0.
310
311If the class exists on disk, but loading from disk results in an error
312( i.e.: a syntax error ), then it will C<croak> with that error.
313
314This is useful for using if you want a fallback module system, i.e.:
315
316 my $class = load_optional_class($foo) ? $foo : $default;
317
318That way, if $foo does exist, but can't be loaded due to error, you won't
319get the behaviour of it simply not existing.
320
321=head1 SEE ALSO
322
323=over 4
324
325=item L<http://blog.fox.geek.nz/2010/11/searching-design-spec-for-ultimate.html>
326
327This blog post is a good overview of the current state of the existing modules
328for loading other modules in various ways.
329
330=item L<http://blog.fox.geek.nz/2010/11/handling-optional-requirements-with.html>
331
332This blog post describes how to handle optional modules with L<Class::Load>.
333
334=item L<http://d.hatena.ne.jp/tokuhirom/20110202/1296598578>
335
336This Japanese blog post describes why L<DBIx::Skinny> now uses L<Class::Load>
337over its competitors.
338
339=item L<Moose>, L<Jifty>, L<Prophet>, etc
340
341This module was designed to be used anywhere you have
342C<if (eval "require $module"; 1)>, which occurs in many large projects.
343
344=back
345
346=head1 AUTHOR
347
348Shawn M Moore <sartak at bestpractical.com>
349
350=head1 COPYRIGHT AND LICENSE
351
352This software is copyright (c) 2012 by Shawn M Moore.
353
354This is free software; you can redistribute it and/or modify it under
355the same terms as the Perl 5 programming language system itself.
356
357=cut
358
359
360__END__
 
# spent 800ns within Class::Load::CORE:match which was called: # once (800ns+0s) by Class::Load::load_first_existing_class at line 65
sub Class::Load::CORE:match; # opcode
# spent 8µs within Class::Load::CORE:regcomp which was called: # once (8µs+0s) by Class::Load::load_first_existing_class at line 65
sub Class::Load::CORE:regcomp; # opcode
# spent 4µs within Class::Load::CORE:subst which was called: # once (4µs+0s) by Class::Load::_error at line 189
sub Class::Load::CORE:subst; # opcode