Profile of Class/Load.pm

← Index
NYTProf Performance Profile «block view•line view•sub view»
For xt/tapper-mcp-scheduler-with-db-longrun.t
Run on Tue May 22 17:18:39 2012
Reported on Tue May 22 17:22:40 2012

Filename | /2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/Class/Load.pm
Statements | Executed 858 statements in 3.03ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
72 | 1 | 1 | 878µs | 103ms | Class::Load::::try_load_classClass::Load::try_load_class (recurses: max depth 1, inclusive time 71µs)
1 | 1 | 1 | 799µs | 1.54ms | Class::Load::::BEGIN@7Class::Load::BEGIN@7
1 | 1 | 1 | 691µs | 2.75ms | Class::Load::::BEGIN@9Class::Load::BEGIN@9
72 | 8 | 7 | 568µs | 103ms | Class::Load::::load_classClass::Load::load_class (recurses: max depth 1, inclusive time 87µs)
1 | 1 | 1 | 555µs | 9.02ms | Class::Load::::BEGIN@8Class::Load::BEGIN@8
6 | 1 | 1 | 87µs | 99.8ms | Class::Load::::__ANON__[:180]Class::Load::__ANON__[:180]
1 | 1 | 1 | 11µs | 14µs | Class::Load::::BEGIN@5Class::Load::BEGIN@5
1 | 1 | 1 | 11µs | 48µs | Class::Load::::BEGIN@10Class::Load::BEGIN@10
1 | 1 | 1 | 6µs | 15µs | Class::Load::::BEGIN@6Class::Load::BEGIN@6
1 | 1 | 1 | 6µs | 33µs | Class::Load::::BEGIN@16Class::Load::BEGIN@16
0 | 0 | 0 | 0s | 0s | Class::Load::::__ANON__[:152]Class::Load::__ANON__[:152]
0 | 0 | 0 | 0s | 0s | Class::Load::::__ANON__[:155]Class::Load::__ANON__[:155]
0 | 0 | 0 | 0s | 0s | Class::Load::::__ANON__[:183]Class::Load::__ANON__[:183]
0 | 0 | 0 | 0s | 0s | Class::Load::::_croakClass::Load::_croak
0 | 0 | 0 | 0s | 0s | Class::Load::::_errorClass::Load::_error
0 | 0 | 0 | 0s | 0s | Class::Load::::_nonexistent_fail_reClass::Load::_nonexistent_fail_re
0 | 0 | 0 | 0s | 0s | Class::Load::::_or_listClass::Load::_or_list
0 | 0 | 0 | 0s | 0s | Class::Load::::_version_fail_reClass::Load::_version_fail_re
0 | 0 | 0 | 0s | 0s | Class::Load::::load_first_existing_classClass::Load::load_first_existing_class
0 | 0 | 0 | 0s | 0s | Class::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
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | package Class::Load;
2 |  |  |  |  | {
3 | 2 | 1µs |  |  | $Class::Load::VERSION = '0.19';
4 |  |  |  |  | }
5 | 3 | 17µs | 2 | 17µs | # spent 14µs (11+3) within Class::Load::BEGIN@5 which was called: # once (11µs+3µs) by Moose::BEGIN@15 at line 5 use strict; # spent 14µs making 1 call to Class::Load::BEGIN@5 # spent 3µs making 1 call to strict::import
6 | 3 | 21µs | 2 | 25µs | # spent 15µs (6+9) within Class::Load::BEGIN@6 which was called: # once (6µs+9µs) by Moose::BEGIN@15 at line 6 use warnings; # spent 15µs making 1 call to Class::Load::BEGIN@6 # spent 9µs making 1 call to warnings::import
7 | 3 | 92µs | 2 | 1.61ms | # spent 1.54ms (799µs+739µs) within Class::Load::BEGIN@7 which was called: # once (799µs+739µs) by Moose::BEGIN@15 at line 7 use base 'Exporter'; # spent 1.54ms making 1 call to Class::Load::BEGIN@7 # spent 70µs making 1 call to base::import
8 | 3 | 84µs | 2 | 9.09ms | # spent 9.02ms (555µs+8.46) within Class::Load::BEGIN@8 which was called: # once (555µs+8.46ms) by Moose::BEGIN@15 at line 8 use Data::OptList 'mkopt'; # spent 9.02ms making 1 call to Class::Load::BEGIN@8 # spent 75µs making 1 call to Sub::Install::__ANON__[Sub/Install.pm:284]
9 | 3 | 134µs | 2 | 2.76ms | # spent 2.75ms (691µs+2.06) within Class::Load::BEGIN@9 which was called: # once (691µs+2.06ms) by Moose::BEGIN@15 at line 9 use Module::Implementation 0.04; # spent 2.75ms making 1 call to Class::Load::BEGIN@9 # spent 14µs making 1 call to UNIVERSAL::VERSION
10 |  |  | 1 | 29µs | # spent 48µs (11+38) within Class::Load::BEGIN@10 which was called: # once (11µs+38µs) by Moose::BEGIN@15 at line 15 use Module::Runtime 0.012 qw( # spent 29µs making 1 call to Module::Runtime::import
11 |  |  |  |  | check_module_name
12 |  |  |  |  | module_notional_filename
13 |  |  |  |  | require_module
14 |  |  |  |  | use_module
15 | 3 | 31µs | 2 | 57µs | ); # spent 48µs making 1 call to Class::Load::BEGIN@10 # spent 9µs making 1 call to UNIVERSAL::VERSION
16 | 3 | 764µs | 2 | 61µs | # spent 33µs (6+27) within Class::Load::BEGIN@16 which was called: # once (6µs+27µs) by Moose::BEGIN@15 at line 16 use Try::Tiny; # spent 33µs making 1 call to Class::Load::BEGIN@16 # spent 27µs making 1 call to Exporter::import
17 |  |  |  |  |
18 |  |  |  |  | {
19 | 3 | 7µs | 1 | 29µs | my $loader = Module::Implementation::build_loader_sub( # spent 29µs making 1 call to Module::Implementation::build_loader_sub
20 |  |  |  |  | implementations => [ 'XS', 'PP' ],
21 |  |  |  |  | symbols => ['is_class_loaded'],
22 |  |  |  |  | );
23 |  |  |  |  |
24 |  |  | 1 | 569µs | $loader->(); # spent 569µs making 1 call to Module::Implementation::__ANON__[Module/Implementation.pm:44]
25 |  |  |  |  | }
26 |  |  |  |  |
27 | 1 | 2µs |  |  | our @EXPORT_OK = qw/load_class load_optional_class try_load_class is_class_loaded load_first_existing_class/;
28 | 1 | 1µs |  |  | our %EXPORT_TAGS = (
29 |  |  |  |  | all => \@EXPORT_OK,
30 |  |  |  |  | );
31 |  |  |  |  |
32 | 1 | 200ns |  |  | our $ERROR;
33 |  |  |  |  |
34 |  |  |  |  | # spent 103ms (568µs+103) within Class::Load::load_class which was called 72 times, avg 1.44ms/call: # 30 times (220µs+1.09ms) by Class::MOP::Class::_inline_constructor at line 1436 of Class/MOP/Class.pm, avg 44µs/call # 13 times (84µs+1.81ms) by Class::MOP::MiniTrait::apply at line 18 of Class/MOP/MiniTrait.pm, avg 146µs/call # 10 times (86µs+6.07ms) by Moose::Meta::Class::superclasses at line 554 of Moose/Meta/Class.pm, avg 615µs/call # 9 times (60µs+363µs) by Moose::Meta::Class::_inline_create_error at line 833 of Moose/Meta/Class.pm, avg 47µs/call # 4 times (65µs+93.2ms) by Moose::Util::_apply_all_roles at line 132 of Moose/Util.pm, avg 23.3ms/call # 4 times (33µs+233µs) by Moose::Meta::Role::apply at line 459 of Moose/Meta/Role.pm, avg 66µs/call # once (14µs+96µs) by MooseX::Traits::Util::resolve_traits at line 77 of Class/MOP.pm # once (6µs+32µs) by metaclass::import at line 32 of metaclass.pm sub load_class {
35 | 288 | 542µs |  |  | my $class = shift;
36 |  |  |  |  | my $options = shift;
37 |  |  |  |  |
38 |  |  | 72 | 103ms | my ($res, $e) = try_load_class($class, $options); # spent 103ms making 72 calls to Class::Load::try_load_class, avg 1.43ms/call, recursion: max depth 1, sum of overlapping time 71µs
39 |  |  |  |  | return 1 if $res;
40 |  |  |  |  |
41 |  |  |  |  | _croak($e);
42 |  |  |  |  | }
43 |  |  |  |  |
44 |  |  |  |  | sub load_first_existing_class {
45 |  |  |  |  | my $classes = Data::OptList::mkopt(\@_)
46 |  |  |  |  | or return;
47 |  |  |  |  |
48 |  |  |  |  | foreach my $class (@{$classes}) {
49 |  |  |  |  | check_module_name($class->[0]);
50 |  |  |  |  | }
51 |  |  |  |  |
52 |  |  |  |  | for my $class (@{$classes}) {
53 |  |  |  |  | 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.
57 |  |  |  |  | return $name if is_class_loaded($name, ($options ? $options : ()));
58 |  |  |  |  |
59 |  |  |  |  | my ($res, $e) = try_load_class($name, $options);
60 |  |  |  |  |
61 |  |  |  |  | return $name if $res;
62 |  |  |  |  |
63 |  |  |  |  | my $file = module_notional_filename($name);
64 |  |  |  |  |
65 |  |  |  |  | next if $e =~ /^Can't locate \Q$file\E in \@INC/;
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 |  |  |  |  |
88 |  |  |  |  | sub _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 |  |  |  |  |
95 |  |  |  |  | sub _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 |  |  |  |  |
102 |  |  |  |  | sub _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 |  |  |  |  |
115 |  |  |  |  | sub 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($ERROR);
133 |  |  |  |  | }
134 |  |  |  |  |
135 |  |  |  |  | # spent 103ms (878µs+102) within Class::Load::try_load_class which was called 72 times, avg 1.43ms/call: # 72 times (878µs+102ms) by Class::Load::load_class at line 38, avg 1.43ms/call sub try_load_class {
136 | 450 | 1.02ms |  |  | my $class = shift;
137 |  |  |  |  | my $options = shift;
138 |  |  |  |  |
139 |  |  | 72 | 1.68ms | check_module_name($class); # spent 1.68ms making 72 calls to Module::Runtime::check_module_name, avg 23µs/call
140 |  |  |  |  |
141 |  |  |  |  | local $@;
142 |  |  |  |  | undef $ERROR;
143 |  |  |  |  |
144 | 66 | 223µs | 72 | 336µs | if (is_class_loaded($class)) { # spent 336µs making 72 calls to Class::Load::XS::is_class_loaded, avg 5µ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.
148 |  |  |  |  | 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 |  |  |  |  |
158 |  |  | 6 | 123µs | my $file = module_notional_filename($class); # spent 123µs making 6 calls to Module::Runtime::module_notional_filename, avg 20µ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.
170 |  |  |  |  | delete $INC{$file};
171 |  |  |  |  | # spent 99.8ms (87µs+99.7) within Class::Load::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/Class/Load.pm:180] which was called 6 times, avg 16.6ms/call: # 6 times (87µs+99.7ms) by Try::Tiny::try at line 71 of Try/Tiny.pm, avg 16.6ms/call return try {
172 | 18 | 70µs |  |  | local $SIG{__DIE__} = 'DEFAULT';
173 | 6 | 13µs |  |  | if ($options && defined $options->{-version}) {
174 |  |  |  |  | use_module($class, $options->{-version});
175 |  |  |  |  | }
176 |  |  |  |  | else {
177 |  |  | 6 | 99.7ms | require_module($class); # spent 99.7ms making 6 calls to Module::Runtime::require_module, avg 16.6ms/call
178 |  |  |  |  | }
179 |  |  |  |  | 1;
180 |  |  |  |  | }
181 |  |  |  |  | catch {
182 |  |  |  |  | _error($_);
183 |  |  | 12 | 99.9ms | }; # spent 99.9ms making 6 calls to Try::Tiny::try, avg 16.6ms/call # spent 43µs making 6 calls to Try::Tiny::catch, avg 7µs/call
184 |  |  |  |  | }
185 |  |  |  |  |
186 |  |  |  |  | sub _error {
187 |  |  |  |  | $ERROR = shift;
188 |  |  |  |  | return 0 unless wantarray;
189 |  |  |  |  | return 0, $ERROR;
190 |  |  |  |  | }
191 |  |  |  |  |
192 |  |  |  |  | sub _croak {
193 |  |  |  |  | require Carp;
194 |  |  |  |  | local $Carp::CarpLevel = $Carp::CarpLevel + 1;
195 |  |  |  |  | Carp::croak(shift);
196 |  |  |  |  | }
197 |  |  |  |  |
198 | 1 | 10µs |  |  | 1;
199 |  |  |  |  |
200 |  |  |  |  | # ABSTRACT: a working (require "Class::Name") and more
201 |  |  |  |  |
- - |  |  |  |  |
204 |  |  |  |  | =pod
205 |  |  |  |  |
206 |  |  |  |  | =head1 NAME
207 |  |  |  |  |
208 |  |  |  |  | Class::Load - a working (require "Class::Name") and more
209 |  |  |  |  |
210 |  |  |  |  | =head1 VERSION
211 |  |  |  |  |
212 |  |  |  |  | version 0.19
213 |  |  |  |  |
214 |  |  |  |  | =head1 SYNOPSIS
215 |  |  |  |  |
216 |  |  |  |  | use Class::Load ':all';
217 |  |  |  |  |
218 |  |  |  |  | try_load_class('Class::Name')
219 |  |  |  |  | or plan skip_all => "Class::Name required to run these tests";
220 |  |  |  |  |
221 |  |  |  |  | load_class('Class::Name');
222 |  |  |  |  |
223 |  |  |  |  | is_class_loaded('Class::Name');
224 |  |  |  |  |
225 |  |  |  |  | my $baseclass = load_optional_class('Class::Name::MightExist')
226 |  |  |  |  | ? 'Class::Name::MightExist'
227 |  |  |  |  | : 'Class::Name::Default';
228 |  |  |  |  |
229 |  |  |  |  | =head1 DESCRIPTION
230 |  |  |  |  |
231 |  |  |  |  | C<require EXPR> only accepts C<Class/Name.pm> style module names, not
232 |  |  |  |  | C<Class::Name>. How frustrating! For that, we provide
233 |  |  |  |  | C<load_class 'Class::Name'>.
234 |  |  |  |  |
235 |  |  |  |  | It's often useful to test whether a module can be loaded, instead of throwing
236 |  |  |  |  | an error when it's not available. For that, we provide
237 |  |  |  |  | C<try_load_class 'Class::Name'>.
238 |  |  |  |  |
239 |  |  |  |  | Finally, sometimes we need to know whether a particular class has been loaded.
240 |  |  |  |  | Asking C<%INC> is an option, but that will miss inner packages and any class
241 |  |  |  |  | for which the filename does not correspond to the package name. For that, we
242 |  |  |  |  | provide C<is_class_loaded 'Class::Name'>.
243 |  |  |  |  |
244 |  |  |  |  | =head1 FUNCTIONS
245 |  |  |  |  |
246 |  |  |  |  | =head2 load_class Class::Name, \%options
247 |  |  |  |  |
248 |  |  |  |  | C<load_class> will load C<Class::Name> or throw an error, much like C<require>.
249 |  |  |  |  |
250 |  |  |  |  | If C<Class::Name> is already loaded (checked with C<is_class_loaded>) then it
251 |  |  |  |  | will not try to load the class. This is useful when you have inner packages
252 |  |  |  |  | which C<require> does not check.
253 |  |  |  |  |
254 |  |  |  |  | The C<%options> hash currently accepts one key, C<-version>. If you specify a
255 |  |  |  |  | version, then this subroutine will call C<< Class::Name->VERSION(
256 |  |  |  |  | $options{-version} ) >> internally, which will throw an error if the class's
257 |  |  |  |  | version is not equal to or greater than the version you requested.
258 |  |  |  |  |
259 |  |  |  |  | =head2 try_load_class Class::Name, \%options -> (0|1, error message)
260 |  |  |  |  |
261 |  |  |  |  | Returns 1 if the class was loaded, 0 if it was not. If the class was not
262 |  |  |  |  | loaded, the error will be returned as a second return value in list context.
263 |  |  |  |  |
264 |  |  |  |  | Again, if C<Class::Name> is already loaded (checked with C<is_class_loaded>)
265 |  |  |  |  | then it will not try to load the class. This is useful when you have inner
266 |  |  |  |  | packages which C<require> does not check.
267 |  |  |  |  |
268 |  |  |  |  | Like C<load_class>, you can pass a C<-version> in C<%options>. If the version
269 |  |  |  |  | is not sufficient, then this subroutine will return false.
270 |  |  |  |  |
271 |  |  |  |  | =head2 is_class_loaded Class::Name, \%options -> 0|1
272 |  |  |  |  |
273 |  |  |  |  | This uses a number of heuristics to determine if the class C<Class::Name> is
274 |  |  |  |  | loaded. There heuristics were taken from L<Class::MOP>'s old pure-perl
275 |  |  |  |  | implementation.
276 |  |  |  |  |
277 |  |  |  |  | Like C<load_class>, you can pass a C<-version> in C<%options>. If the version
278 |  |  |  |  | is not sufficient, then this subroutine will return false.
279 |  |  |  |  |
280 |  |  |  |  | =head2 load_first_existing_class Class::Name, \%options, ...
281 |  |  |  |  |
282 |  |  |  |  | This attempts to load the first loadable class in the list of classes
283 |  |  |  |  | given. Each class name can be followed by an options hash reference.
284 |  |  |  |  |
285 |  |  |  |  | If any one of the classes loads and passes the optional version check, that
286 |  |  |  |  | class name will be returned. If I<none> of the classes can be loaded (or none
287 |  |  |  |  | pass their version check), then an error will be thrown.
288 |  |  |  |  |
289 |  |  |  |  | If, when attempting to load a class, it fails to load because of a syntax
290 |  |  |  |  | error, then an error will be thrown immediately.
291 |  |  |  |  |
292 |  |  |  |  | =head2 load_optional_class Class::Name, \%options -> 0|1
293 |  |  |  |  |
294 |  |  |  |  | C<load_optional_class> is a lot like C<try_load_class>, but also a lot like
295 |  |  |  |  | C<load_class>.
296 |  |  |  |  |
297 |  |  |  |  | If the class exists, and it works, then it will return 1. If you specify a
298 |  |  |  |  | version in C<%options>, then the version check must succeed or it will return
299 |  |  |  |  | 0.
300 |  |  |  |  |
301 |  |  |  |  | If the class doesn't exist, and it appears to not exist on disk either, it
302 |  |  |  |  | will return 0.
303 |  |  |  |  |
304 |  |  |  |  | If the class exists on disk, but loading from disk results in an error
305 |  |  |  |  | ( i.e.: a syntax error ), then it will C<croak> with that error.
306 |  |  |  |  |
307 |  |  |  |  | This is useful for using if you want a fallback module system, i.e.:
308 |  |  |  |  |
309 |  |  |  |  | my $class = load_optional_class($foo) ? $foo : $default;
310 |  |  |  |  |
311 |  |  |  |  | That way, if $foo does exist, but can't be loaded due to error, you won't
312 |  |  |  |  | get the behaviour of it simply not existing.
313 |  |  |  |  |
314 |  |  |  |  | =head1 SEE ALSO
315 |  |  |  |  |
316 |  |  |  |  | =over 4
317 |  |  |  |  |
318 |  |  |  |  | =item L<http://blog.fox.geek.nz/2010/11/searching-design-spec-for-ultimate.html>
319 |  |  |  |  |
320 |  |  |  |  | This blog post is a good overview of the current state of the existing modules
321 |  |  |  |  | for loading other modules in various ways.
322 |  |  |  |  |
323 |  |  |  |  | =item L<http://blog.fox.geek.nz/2010/11/handling-optional-requirements-with.html>
324 |  |  |  |  |
325 |  |  |  |  | This blog post describes how to handle optional modules with L<Class::Load>.
326 |  |  |  |  |
327 |  |  |  |  | =item L<http://d.hatena.ne.jp/tokuhirom/20110202/1296598578>
328 |  |  |  |  |
329 |  |  |  |  | This Japanese blog post describes why L<DBIx::Skinny> now uses L<Class::Load>
330 |  |  |  |  | over its competitors.
331 |  |  |  |  |
332 |  |  |  |  | =item L<Moose>, L<Jifty>, L<Prophet>, etc
333 |  |  |  |  |
334 |  |  |  |  | This module was designed to be used anywhere you have
335 |  |  |  |  | C<if (eval "require $module"; 1)>, which occurs in many large projects.
336 |  |  |  |  |
337 |  |  |  |  | =back
338 |  |  |  |  |
339 |  |  |  |  | =head1 AUTHOR
340 |  |  |  |  |
341 |  |  |  |  | Shawn M Moore <sartak at bestpractical.com>
342 |  |  |  |  |
343 |  |  |  |  | =head1 COPYRIGHT AND LICENSE
344 |  |  |  |  |
345 |  |  |  |  | This software is copyright (c) 2012 by Shawn M Moore.
346 |  |  |  |  |
347 |  |  |  |  | This is free software; you can redistribute it and/or modify it under
348 |  |  |  |  | the same terms as the Perl 5 programming language system itself.
349 |  |  |  |  |
350 |  |  |  |  | =cut
351 |  |  |  |  |
352 |  |  |  |  |
353 |  |  |  |  | __END__