File | /opt/wise/lib/perl5/5.10.0/mro.pm | Statements Executed | 44 | Total Time | 0.000983 seconds |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine | |
---|---|---|---|---|---|---|
19 | 1 | 2 | 0.00060 | 0.00060 | mro:: | _nextcan (xsub) |
93 | 1 | 2 | 0.00035 | 0.00035 | mro:: | method_changed_in (xsub) |
18 | 5 | 5 | 0.00025 | 0.00085 | next:: | method |
11 | 1 | 2 | 6.3e-5 | 6.3e-5 | mro:: | set_mro (xsub) |
8 | 1 | 2 | 3.1e-5 | 3.1e-5 | mro:: | get_linear_isa (xsub) |
0 | 0 | 0 | 0 | 0 | maybe::next:: | method |
0 | 0 | 0 | 0 | 0 | mro:: | BEGIN |
0 | 0 | 0 | 0 | 0 | mro:: | import |
0 | 0 | 0 | 0 | 0 | next:: | can |
Line | Stmts. | 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 | # | |||
8 | package mro; | |||
9 | 3 | 4.5e-5 | 1.5e-5 | use strict; # spent 25µs making 1 call to strict::import |
10 | 3 | 0.00016 | 5.3e-5 | use 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 | |||
14 | 1 | 1.0e-6 | 1.0e-6 | our $VERSION = '1.00'; |
15 | ||||
16 | sub import { | |||
17 | mro::set_mro(scalar(caller), $_[1]) if $_[1]; | |||
18 | } | |||
19 | ||||
20 | package # hide me from PAUSE | |||
21 | next; | |||
22 | ||||
23 | sub 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 | |||
26 | 18 | 0.00068 | 3.8e-5 | my $method = mro::_nextcan($_[0], 1); # spent 601µs making 18 calls to mro::_nextcan, avg 33µs/call |
27 | 18 | 9.8e-5 | 5.4e-6 | goto &$method; |
28 | } | |||
29 | ||||
30 | package # hide me from PAUSE | |||
31 | maybe::next; | |||
32 | ||||
33 | sub method { | |||
34 | my $method = mro::_nextcan($_[0], 0); | |||
35 | goto &$method if defined $method; | |||
36 | return; | |||
37 | } | |||
38 | ||||
39 | 1 | 4.0e-6 | 4.0e-6 | 1; |
40 | ||||
41 | __END__ | |||
42 | ||||
43 | =head1 NAME | |||
44 | ||||
45 | mro - 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 | ||||
56 | The "mro" namespace provides several utilities for dealing | |||
57 | with method resolution order and method caching in general. | |||
58 | ||||
59 | These interfaces are only available in Perl 5.9.5 and higher. | |||
60 | See L<MRO::Compat> on CPAN for a mostly forwards compatible | |||
61 | implementation for older Perls. | |||
62 | ||||
63 | =head1 OVERVIEW | |||
64 | ||||
65 | It's possible to change the MRO of a given class either by using C<use | |||
66 | mro> as shown in the synopsis, or by using the L</mro::set_mro> function | |||
67 | below. The functions in the mro namespace do not require loading the | |||
68 | C<mro> module, as they are actually provided by the core perl interpreter. | |||
69 | ||||
70 | The special methods C<next::method>, C<next::can>, and | |||
71 | C<maybe::next::method> are not available until this C<mro> module | |||
72 | has been loaded via C<use> or C<require>. | |||
73 | ||||
74 | =head1 The C3 MRO | |||
75 | ||||
76 | In addition to the traditional Perl default MRO (depth first | |||
77 | search, called C<DFS> here), Perl now offers the C3 MRO as | |||
78 | well. Perl's support for C3 is based on the work done in | |||
79 | Stevan Little's module L<Class::C3>, and most of the C3-related | |||
80 | documentation here is ripped directly from there. | |||
81 | ||||
82 | =head2 What is C3? | |||
83 | ||||
84 | C3 is the name of an algorithm which aims to provide a sane method | |||
85 | resolution order under multiple inheritance. It was first introduced in | |||
86 | the language Dylan (see links in the L</"SEE ALSO"> section), and then | |||
87 | later adopted as the preferred MRO (Method Resolution Order) for the | |||
88 | new-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 | |||
90 | as well. | |||
91 | ||||
92 | =head2 How does C3 work | |||
93 | ||||
94 | C3 works by always preserving local precendence ordering. This essentially | |||
95 | means that no class will appear before any of its subclasses. Take, for | |||
96 | instance, the classic diamond inheritance pattern: | |||
97 | ||||
98 | <A> | |||
99 | / \ | |||
100 | <B> <C> | |||
101 | \ / | |||
102 | <D> | |||
103 | ||||
104 | The standard Perl 5 MRO would be (D, B, A, C). The result being that B<A> | |||
105 | appears before B<C>, even though B<C> is the subclass of B<A>. The C3 MRO | |||
106 | algorithm however, produces the following order: (D, B, C, A), which does | |||
107 | not have this issue. | |||
108 | ||||
109 | This example is fairly trivial; for more complex cases and a deeper | |||
110 | explanation, see the links in the L</"SEE ALSO"> section. | |||
111 | ||||
112 | =head1 Functions | |||
113 | ||||
114 | =head2 mro::get_linear_isa($classname[, $type]) | |||
115 | ||||
116 | Returns an arrayref which is the linearized MRO of the given class. | |||
117 | Uses whichever MRO is currently in effect for that class by default, | |||
118 | or the given MRO (either C<c3> or C<dfs> if specified as C<$type>). | |||
119 | ||||
120 | The linearized MRO of a class is an ordered array of all of the | |||
121 | classes one would search when resolving a method on that class, | |||
122 | starting with the class itself. | |||
123 | ||||
124 | If the requested class doesn't yet exist, this function will still | |||
125 | succeed, and return C<[ $classname ]> | |||
126 | ||||
127 | Note that C<UNIVERSAL> (and any members of C<UNIVERSAL>'s MRO) are not | |||
128 | part of the MRO of a class, even though all classes implicitly inherit | |||
129 | methods from C<UNIVERSAL> and its parents. | |||
130 | ||||
131 | =head2 mro::set_mro($classname, $type) | |||
132 | ||||
133 | Sets the MRO of the given class to the C<$type> argument (either | |||
134 | C<c3> or C<dfs>). | |||
135 | ||||
136 | =head2 mro::get_mro($classname) | |||
137 | ||||
138 | Returns the MRO of the given class (either C<c3> or C<dfs>). | |||
139 | ||||
140 | =head2 mro::get_isarev($classname) | |||
141 | ||||
142 | Gets the C<mro_isarev> for this class, returned as an | |||
143 | arrayref of class names. These are every class that "isa" | |||
144 | the given class name, even if the isa relationship is | |||
145 | indirect. This is used internally by the MRO code to | |||
146 | keep track of method/MRO cache invalidations. | |||
147 | ||||
148 | Currently, this list only grows, it never shrinks. This | |||
149 | was a performance consideration (properly tracking and | |||
150 | deleting isarev entries when someone removes an entry | |||
151 | from an C<@ISA> is costly, and it doesn't happen often | |||
152 | anyways). The fact that a class which no longer truly | |||
153 | "isa" this class at runtime remains on the list should be | |||
154 | considered a quirky implementation detail which is subject | |||
155 | to future change. It shouldn't be an issue as long as | |||
156 | you're looking at this list for the same reasons the | |||
157 | core code does: as a performance optimization | |||
158 | over having to search every class in existence. | |||
159 | ||||
160 | As with C<mro::get_mro> above, C<UNIVERSAL> is special. | |||
161 | C<UNIVERSAL> (and parents') isarev lists do not include | |||
162 | every class in existence, even though all classes are | |||
163 | effectively descendants for method inheritance purposes. | |||
164 | ||||
165 | =head2 mro::is_universal($classname) | |||
166 | ||||
167 | Returns a boolean status indicating whether or not | |||
168 | the given classname is either C<UNIVERSAL> itself, | |||
169 | or one of C<UNIVERSAL>'s parents by C<@ISA> inheritance. | |||
170 | ||||
171 | Any class for which this function returns true is | |||
172 | "universal" in the sense that all classes potentially | |||
173 | inherit methods from it. | |||
174 | ||||
175 | For similar reasons to C<isarev> above, this flag is | |||
176 | permanent. Once it is set, it does not go away, even | |||
177 | if the class in question really isn't universal anymore. | |||
178 | ||||
179 | =head2 mro::invalidate_all_method_caches() | |||
180 | ||||
181 | Increments C<PL_sub_generation>, which invalidates method | |||
182 | caching in all packages. | |||
183 | ||||
184 | =head2 mro::method_changed_in($classname) | |||
185 | ||||
186 | Invalidates the method cache of any classes dependent on the | |||
187 | given class. This is not normally necessary. The only | |||
188 | known case where pure perl code can confuse the method | |||
189 | cache is when you manually install a new constant | |||
190 | subroutine by using a readonly scalar value, like the | |||
191 | internals of L<constant> do. If you find another case, | |||
192 | please report it so we can either fix it or document | |||
193 | the exception here. | |||
194 | ||||
195 | =head2 mro::get_pkg_gen($classname) | |||
196 | ||||
197 | Returns an integer which is incremented every time a | |||
198 | real local method in the package C<$classname> changes, | |||
199 | or the local C<@ISA> of C<$classname> is modified. | |||
200 | ||||
201 | This is intended for authors of modules which do lots | |||
202 | of class introspection, as it allows them to very quickly | |||
203 | check if anything important about the local properties | |||
204 | of a given class have changed since the last time they | |||
205 | looked. It does not increment on method/C<@ISA> | |||
206 | changes in superclasses. | |||
207 | ||||
208 | It's still up to you to seek out the actual changes, | |||
209 | and there might not actually be any. Perhaps all | |||
210 | of the changes since you last checked cancelled each | |||
211 | other out and left the package in the state it was in | |||
212 | before. | |||
213 | ||||
214 | This integer normally starts off at a value of C<1> | |||
215 | when a package stash is instantiated. Calling it | |||
216 | on packages whose stashes do not exist at all will | |||
217 | return C<0>. If a package stash is completely | |||
218 | deleted (not a normal occurence, but it can happen | |||
219 | if someone does something like C<undef %PkgName::>), | |||
220 | the number will be reset to either C<0> or C<1>, | |||
221 | depending on how completely package was wiped out. | |||
222 | ||||
223 | =head2 next::method | |||
224 | ||||
225 | This is somewhat like C<SUPER>, but it uses the C3 method | |||
226 | resolution order to get better consistency in multiple | |||
227 | inheritance situations. Note that while inheritance in | |||
228 | general follows whichever MRO is in effect for the | |||
229 | given class, C<next::method> only uses the C3 MRO. | |||
230 | ||||
231 | One 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 | ||||
239 | Note that you don't (re-)specify the method name. | |||
240 | It forces you to always use the same method name | |||
241 | as the method you started in. | |||
242 | ||||
243 | It can be called on an object or a class, of course. | |||
244 | ||||
245 | The way it resolves which actual method to call is: | |||
246 | ||||
247 | =over 4 | |||
248 | ||||
249 | =item 1 | |||
250 | ||||
251 | First, it determines the linearized C3 MRO of | |||
252 | the object or class it is being called on. | |||
253 | ||||
254 | =item 2 | |||
255 | ||||
256 | Then, it determines the class and method name | |||
257 | of the context it was invoked from. | |||
258 | ||||
259 | =item 3 | |||
260 | ||||
261 | Finally, it searches down the C3 MRO list until | |||
262 | it reaches the contextually enclosing class, then | |||
263 | searches further down the MRO list for the next | |||
264 | method with the same name as the contextually | |||
265 | enclosing method. | |||
266 | ||||
267 | =back | |||
268 | ||||
269 | Failure to find a next method will result in an | |||
270 | exception being thrown (see below for alternatives). | |||
271 | ||||
272 | This is substantially different than the behavior | |||
273 | of C<SUPER> under complex multiple inheritance. | |||
274 | (This becomes obvious when one realizes that the | |||
275 | common superclasses in the C3 linearizations of | |||
276 | a given class and one of its parents will not | |||
277 | always be ordered the same for both.) | |||
278 | ||||
279 | B<Caveat>: Calling C<next::method> from methods defined outside the class: | |||
280 | ||||
281 | There is an edge case when using C<next::method> from within a subroutine | |||
282 | which was created in a different module than the one it is called from. It | |||
283 | sounds complicated, but it really isn't. Here is an example which will not | |||
284 | work correctly: | |||
285 | ||||
286 | *Foo::foo = sub { (shift)->next::method(@_) }; | |||
287 | ||||
288 | The problem exists because the anonymous subroutine being assigned to the | |||
289 | C<*Foo::foo> glob will show up in the call stack as being called | |||
290 | C<__ANON__> and not C<foo> as you might expect. Since C<next::method> uses | |||
291 | C<caller> to find the name of the method it was called in, it will fail in | |||
292 | this case. | |||
293 | ||||
294 | But fear not, there's a simple solution. The module C<Sub::Name> will | |||
295 | reach into the perl internals and assign a name to an anonymous subroutine | |||
296 | for you. Simply do this: | |||
297 | ||||
298 | use Sub::Name 'subname'; | |||
299 | *Foo::foo = subname 'Foo::foo' => sub { (shift)->next::method(@_) }; | |||
300 | ||||
301 | and things will Just Work. | |||
302 | ||||
303 | =head2 next::can | |||
304 | ||||
305 | This is similar to C<next::method>, but just returns either a code | |||
306 | reference or C<undef> to indicate that no further methods of this name | |||
307 | exist. | |||
308 | ||||
309 | =head2 maybe::next::method | |||
310 | ||||
311 | In simple cases, it is equivalent to: | |||
312 | ||||
313 | $self->next::method(@_) if $self->next_can; | |||
314 | ||||
315 | But there are some cases where only this solution | |||
316 | works (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 | ||||
374 | Brandon L. Black, E<lt>blblack@gmail.comE<gt> | |||
375 | ||||
376 | Based 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 | ||||
# 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 | ||||
# 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 | ||||
# 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 |