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