← Index
Performance Profile   « block view • line view • sub view »
For /wise/base/deliv/dev/bin/getfix
  Run on Thu May 20 15:30:03 2010
Reported on Thu May 20 16:25:41 2010

File/opt/wise/lib/perl5/5.10.0/mro.pm
Statements Executed44
Total Time0.000983 seconds

Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
19120.000600.00060mro::_nextcan (xsub)
93120.000350.00035mro::method_changed_in (xsub)
18550.000250.00085next::method
11126.3e-56.3e-5mro::set_mro (xsub)
8123.1e-53.1e-5mro::get_linear_isa (xsub)
00000maybe::next::method
00000mro::BEGIN
00000mro::import
00000next::can

LineStmts.Exclusive
Time
Avg.Code
1# mro.pm
2#
3# Copyright (c) 2007 Brandon L Black
4#
5# You may distribute under the terms of either the GNU General Public
6# License or the Artistic License, as specified in the README file.
7#
8package mro;
934.5e-51.5e-5use strict;
# spent 25µs making 1 call to strict::import
1030.000165.3e-5use warnings;
# spent 20µs making 1 call to warnings::import
11
12# mro.pm versions < 1.00 reserved for MRO::Compat
13# for partial back-compat to 5.[68].x
1411.0e-61.0e-6our $VERSION = '1.00';
15
16sub import {
17 mro::set_mro(scalar(caller), $_[1]) if $_[1];
18}
19
20package # hide me from PAUSE
21 next;
22
23sub can { mro::_nextcan($_[0], 0) }
24
25
# spent 847µs (246+601) within next::method which was called 18 times, avg 47µs/call: # 9 times (121µs+478µs) by DBIx::Class::Componentised::inject_base at line 31 of /wise/base/static/lib/perl5/site_perl/5.10.0/DBIx/Class/Componentised.pm, avg 67µs/call # 4 times (70µs+55µs) by DBIx::Class::Storage::DBI::MultiDistinctEmulation::_select at line 18 of /wise/base/static/lib/perl5/site_perl/5.10.0/DBIx/Class/Storage/DBI/MultiDistinctEmulation.pm, avg 31µs/call # 2 times (26µs+18µs) by DBIx::Class::Relationship::ProxyMethods::register_relationship at line 15 of /wise/base/static/lib/perl5/site_perl/5.10.0/DBIx/Class/Relationship/ProxyMethods.pm, avg 22µs/call # 2 times (16µs+21µs) by DBIx::Class::Relationship::Accessor::register_relationship at line 12 of /wise/base/static/lib/perl5/site_perl/5.10.0/DBIx/Class/Relationship/Accessor.pm, avg 18µs/call # once (13µs+29µs) by DBIx::Class::Storage::DBI::new at line 326 of /wise/base/static/lib/perl5/site_perl/5.10.0/DBIx/Class/Storage/DBI.pm
sub method {
26180.000683.8e-5 my $method = mro::_nextcan($_[0], 1);
# spent 601µs making 18 calls to mro::_nextcan, avg 33µs/call
27189.8e-55.4e-6 goto &$method;
28}
29
30package # hide me from PAUSE
31 maybe::next;
32
33sub method {
34 my $method = mro::_nextcan($_[0], 0);
35 goto &$method if defined $method;
36 return;
37}
38
3914.0e-64.0e-61;
40
41__END__
42
43=head1 NAME
44
45mro - Method Resolution Order
46
47=head1 SYNOPSIS
48
49 use mro; # enables next::method and friends globally
50
51 use mro 'dfs'; # enable DFS MRO for this class (Perl default)
52 use mro 'c3'; # enable C3 MRO for this class
53
54=head1 DESCRIPTION
55
56The "mro" namespace provides several utilities for dealing
57with method resolution order and method caching in general.
58
59These interfaces are only available in Perl 5.9.5 and higher.
60See L<MRO::Compat> on CPAN for a mostly forwards compatible
61implementation for older Perls.
62
63=head1 OVERVIEW
64
65It's possible to change the MRO of a given class either by using C<use
66mro> as shown in the synopsis, or by using the L</mro::set_mro> function
67below. The functions in the mro namespace do not require loading the
68C<mro> module, as they are actually provided by the core perl interpreter.
69
70The special methods C<next::method>, C<next::can>, and
71C<maybe::next::method> are not available until this C<mro> module
72has been loaded via C<use> or C<require>.
73
74=head1 The C3 MRO
75
76In addition to the traditional Perl default MRO (depth first
77search, called C<DFS> here), Perl now offers the C3 MRO as
78well. Perl's support for C3 is based on the work done in
79Stevan Little's module L<Class::C3>, and most of the C3-related
80documentation here is ripped directly from there.
81
82=head2 What is C3?
83
84C3 is the name of an algorithm which aims to provide a sane method
85resolution order under multiple inheritance. It was first introduced in
86the language Dylan (see links in the L</"SEE ALSO"> section), and then
87later adopted as the preferred MRO (Method Resolution Order) for the
88new-style classes in Python 2.3. Most recently it has been adopted as the
89"canonical" MRO for Perl 6 classes, and the default MRO for Parrot objects
90as well.
91
92=head2 How does C3 work
93
94C3 works by always preserving local precendence ordering. This essentially
95means that no class will appear before any of its subclasses. Take, for
96instance, the classic diamond inheritance pattern:
97
98 <A>
99 / \
100 <B> <C>
101 \ /
102 <D>
103
104The standard Perl 5 MRO would be (D, B, A, C). The result being that B<A>
105appears before B<C>, even though B<C> is the subclass of B<A>. The C3 MRO
106algorithm however, produces the following order: (D, B, C, A), which does
107not have this issue.
108
109This example is fairly trivial; for more complex cases and a deeper
110explanation, see the links in the L</"SEE ALSO"> section.
111
112=head1 Functions
113
114=head2 mro::get_linear_isa($classname[, $type])
115
116Returns an arrayref which is the linearized MRO of the given class.
117Uses whichever MRO is currently in effect for that class by default,
118or the given MRO (either C<c3> or C<dfs> if specified as C<$type>).
119
120The linearized MRO of a class is an ordered array of all of the
121classes one would search when resolving a method on that class,
122starting with the class itself.
123
124If the requested class doesn't yet exist, this function will still
125succeed, and return C<[ $classname ]>
126
127Note that C<UNIVERSAL> (and any members of C<UNIVERSAL>'s MRO) are not
128part of the MRO of a class, even though all classes implicitly inherit
129methods from C<UNIVERSAL> and its parents.
130
131=head2 mro::set_mro($classname, $type)
132
133Sets the MRO of the given class to the C<$type> argument (either
134C<c3> or C<dfs>).
135
136=head2 mro::get_mro($classname)
137
138Returns the MRO of the given class (either C<c3> or C<dfs>).
139
140=head2 mro::get_isarev($classname)
141
142Gets the C<mro_isarev> for this class, returned as an
143arrayref of class names. These are every class that "isa"
144the given class name, even if the isa relationship is
145indirect. This is used internally by the MRO code to
146keep track of method/MRO cache invalidations.
147
148Currently, this list only grows, it never shrinks. This
149was a performance consideration (properly tracking and
150deleting isarev entries when someone removes an entry
151from an C<@ISA> is costly, and it doesn't happen often
152anyways). The fact that a class which no longer truly
153"isa" this class at runtime remains on the list should be
154considered a quirky implementation detail which is subject
155to future change. It shouldn't be an issue as long as
156you're looking at this list for the same reasons the
157core code does: as a performance optimization
158over having to search every class in existence.
159
160As with C<mro::get_mro> above, C<UNIVERSAL> is special.
161C<UNIVERSAL> (and parents') isarev lists do not include
162every class in existence, even though all classes are
163effectively descendants for method inheritance purposes.
164
165=head2 mro::is_universal($classname)
166
167Returns a boolean status indicating whether or not
168the given classname is either C<UNIVERSAL> itself,
169or one of C<UNIVERSAL>'s parents by C<@ISA> inheritance.
170
171Any class for which this function returns true is
172"universal" in the sense that all classes potentially
173inherit methods from it.
174
175For similar reasons to C<isarev> above, this flag is
176permanent. Once it is set, it does not go away, even
177if the class in question really isn't universal anymore.
178
179=head2 mro::invalidate_all_method_caches()
180
181Increments C<PL_sub_generation>, which invalidates method
182caching in all packages.
183
184=head2 mro::method_changed_in($classname)
185
186Invalidates the method cache of any classes dependent on the
187given class. This is not normally necessary. The only
188known case where pure perl code can confuse the method
189cache is when you manually install a new constant
190subroutine by using a readonly scalar value, like the
191internals of L<constant> do. If you find another case,
192please report it so we can either fix it or document
193the exception here.
194
195=head2 mro::get_pkg_gen($classname)
196
197Returns an integer which is incremented every time a
198real local method in the package C<$classname> changes,
199or the local C<@ISA> of C<$classname> is modified.
200
201This is intended for authors of modules which do lots
202of class introspection, as it allows them to very quickly
203check if anything important about the local properties
204of a given class have changed since the last time they
205looked. It does not increment on method/C<@ISA>
206changes in superclasses.
207
208It's still up to you to seek out the actual changes,
209and there might not actually be any. Perhaps all
210of the changes since you last checked cancelled each
211other out and left the package in the state it was in
212before.
213
214This integer normally starts off at a value of C<1>
215when a package stash is instantiated. Calling it
216on packages whose stashes do not exist at all will
217return C<0>. If a package stash is completely
218deleted (not a normal occurence, but it can happen
219if someone does something like C<undef %PkgName::>),
220the number will be reset to either C<0> or C<1>,
221depending on how completely package was wiped out.
222
223=head2 next::method
224
225This is somewhat like C<SUPER>, but it uses the C3 method
226resolution order to get better consistency in multiple
227inheritance situations. Note that while inheritance in
228general follows whichever MRO is in effect for the
229given class, C<next::method> only uses the C3 MRO.
230
231One generally uses it like so:
232
233 sub some_method {
234 my $self = shift;
235 my $superclass_answer = $self->next::method(@_);
236 return $superclass_answer + 1;
237 }
238
239Note that you don't (re-)specify the method name.
240It forces you to always use the same method name
241as the method you started in.
242
243It can be called on an object or a class, of course.
244
245The way it resolves which actual method to call is:
246
247=over 4
248
249=item 1
250
251First, it determines the linearized C3 MRO of
252the object or class it is being called on.
253
254=item 2
255
256Then, it determines the class and method name
257of the context it was invoked from.
258
259=item 3
260
261Finally, it searches down the C3 MRO list until
262it reaches the contextually enclosing class, then
263searches further down the MRO list for the next
264method with the same name as the contextually
265enclosing method.
266
267=back
268
269Failure to find a next method will result in an
270exception being thrown (see below for alternatives).
271
272This is substantially different than the behavior
273of C<SUPER> under complex multiple inheritance.
274(This becomes obvious when one realizes that the
275common superclasses in the C3 linearizations of
276a given class and one of its parents will not
277always be ordered the same for both.)
278
279B<Caveat>: Calling C<next::method> from methods defined outside the class:
280
281There is an edge case when using C<next::method> from within a subroutine
282which was created in a different module than the one it is called from. It
283sounds complicated, but it really isn't. Here is an example which will not
284work correctly:
285
286 *Foo::foo = sub { (shift)->next::method(@_) };
287
288The problem exists because the anonymous subroutine being assigned to the
289C<*Foo::foo> glob will show up in the call stack as being called
290C<__ANON__> and not C<foo> as you might expect. Since C<next::method> uses
291C<caller> to find the name of the method it was called in, it will fail in
292this case.
293
294But fear not, there's a simple solution. The module C<Sub::Name> will
295reach into the perl internals and assign a name to an anonymous subroutine
296for you. Simply do this:
297
298 use Sub::Name 'subname';
299 *Foo::foo = subname 'Foo::foo' => sub { (shift)->next::method(@_) };
300
301and things will Just Work.
302
303=head2 next::can
304
305This is similar to C<next::method>, but just returns either a code
306reference or C<undef> to indicate that no further methods of this name
307exist.
308
309=head2 maybe::next::method
310
311In simple cases, it is equivalent to:
312
313 $self->next::method(@_) if $self->next_can;
314
315But there are some cases where only this solution
316works (like C<goto &maybe::next::method>);
317
318=head1 SEE ALSO
319
320=head2 The original Dylan paper
321
322=over 4
323
324=item L<http://www.webcom.com/haahr/dylan/linearization-oopsla96.html>
325
326=back
327
328=head2 The prototype Perl 6 Object Model uses C3
329
330=over 4
331
332=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel/>
333
334=back
335
336=head2 Parrot now uses C3
337
338=over 4
339
340=item L<http://aspn.activestate.com/ASPN/Mail/Message/perl6-internals/2746631>
341
342=item L<http://use.perl.org/~autrijus/journal/25768>
343
344=back
345
346=head2 Python 2.3 MRO related links
347
348=over 4
349
350=item L<http://www.python.org/2.3/mro.html>
351
352=item L<http://www.python.org/2.2.2/descrintro.html#mro>
353
354=back
355
356=head2 C3 for TinyCLOS
357
358=over 4
359
360=item L<http://www.call-with-current-continuation.org/eggs/c3.html>
361
362=back
363
364=head2 Class::C3
365
366=over 4
367
368=item L<Class::C3>
369
370=back
371
372=head1 AUTHOR
373
374Brandon L. Black, E<lt>blblack@gmail.comE<gt>
375
376Based on Stevan Little's L<Class::C3>
377
378=cut
# spent 601µs within mro::_nextcan which was called 18 times, avg 33µs/call: # 18 times (601µs+0) by next::method at line 26 of /opt/wise/lib/perl5/5.10.0/mro.pm, avg 33µs/call
sub mro::_nextcan; # xsub
# spent 31µs within mro::get_linear_isa which was called 7 times, avg 4µs/call: # 7 times (31µs+0) by Class::Accessor::Grouped::get_super_paths at line 420 of /wise/base/static/lib/perl5/site_perl/5.10.0/Class/Accessor/Grouped.pm, avg 4µs/call
sub mro::get_linear_isa; # xsub
# spent 355µs within mro::method_changed_in which was called 92 times, avg 4µs/call: # 92 times (355µs+0) by constant::import at line 113 of /opt/wise/lib/perl5/5.10.0/constant.pm, avg 4µs/call
sub mro::method_changed_in; # xsub
# spent 63µs within mro::set_mro which was called 10 times, avg 6µs/call: # 10 times (63µs+0) by Class::C3::import at line 61 of /wise/base/static/lib/perl5/site_perl/5.10.0/Class/C3.pm, avg 6µs/call
sub mro::set_mro; # xsub