[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 use strict; 10 use warnings; 11 12 # mro.pm versions < 1.00 reserved for MRO::Compat 13 # for partial back-compat to 5.[68].x 14 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 sub method { 26 my $method = mro::_nextcan($_[0], 1); 27 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; 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
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 17 22:47:18 2015 | Cross-referenced by PHPXref 0.7.1 |