| 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 | mro::get_linear_isa (xsub) |
| 86 | 1 | 2 | 117µs | 117µs | mro::method_changed_in (xsub) |
| 1 | 1 | 1 | 18µs | 20µs | mro::BEGIN@10 |
| 1 | 1 | 1 | 7µs | 15µs | mro::BEGIN@11 |
| 0 | 0 | 0 | 0s | 0s | maybe::next::method |
| 0 | 0 | 0 | 0s | 0s | mro::import |
| 0 | 0 | 0 | 0s | 0s | next::can |
| 0 | 0 | 0 | 0s | 0s | next::method |
| 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 |