3 # Copyright (c) 2007 Brandon L Black
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.
12 # mro.pm versions < 1.00 reserved for possible CPAN mro dist
13 # (for partial back-compat to 5.[68].x)
14 our $VERSION = '1.00';
17 mro::set_mro(scalar(caller), $_[1]) if $_[1];
26 mro - Method Resolution Order
30 use mro 'dfs'; # enable DFS mro for this class (Perl default)
31 use mro 'c3'; # enable C3 mro for this class
35 The "mro" namespace provides several utilities for dealing
36 with method resolution order and method caching in general.
40 One can change the mro of a given class by either C<use mro>
41 as shown in the synopsis, or by using the L</mro::set_mro>
42 function below. The functions below do not require that one
43 loads the "mro" module, they are provided by the core. The
44 C<use mro> syntax is just syntax sugar for setting the current
49 In addition to the traditional Perl default MRO (depth first
50 search, called C<dfs> here), Perl now offers the C3 MRO as
51 well. Perl's support for C3 is based on the work done in
52 Stevan Little's L<Class::C3>, and most of the C3-related
53 documentation here is ripped directly from there.
57 C3 is the name of an algorithm which aims to provide a sane method resolution order under multiple
58 inheritence. It was first introduced in the langauge Dylan (see links in the L<SEE ALSO> section),
59 and then later adopted as the prefered MRO (Method Resolution Order) for the new-style classes in
60 Python 2.3. Most recently it has been adopted as the 'canonical' MRO for Perl 6 classes, and the
61 default MRO for Parrot objects as well.
63 =head2 How does C3 work.
65 C3 works by always preserving local precendence ordering. This essentially means that no class will appear before any of it's subclasses. Take the classic diamond inheritence pattern for instance:
73 The standard Perl 5 MRO would be (D, B, A, C). The result being that B<A> appears before B<C>, even though B<C> is the subclass of B<A>. The C3 MRO algorithm however, produces the following MRO (D, B, C, A), which does not have this same issue.
75 This example is fairly trival, for more complex examples and a deeper explaination, see the links in the L<SEE ALSO - C3 Links> section.
79 =head2 mro::get_linear_isa
81 Arguments: classname[, type]
83 Return an arrayref which is the linearized MRO of the given class.
84 Uses whichever MRO is currently in effect for that class by default,
85 or the given mro (either C<c3> or C<dfs> if specified as C<type>).
87 C<UNIVERSAL> (and any members of C<UNIVERSAL>'s MRO) are not part
88 of the MRO of a class, even though all classes implicitly inherit
89 methods from C<UNIVERSAL> and its parents.
93 Arguments: classname, type
95 Sets the MRO of the given class to the C<type> argument (either
102 Returns the MRO of the given class (either C<c3> or C<dfs>)
104 =head2 mro::get_isarev
108 Gets the C<mro_isarev> for this class, returned as an
109 array of classnames. These are every class that "isa"
110 the given classname, even if the isa relationship is
111 indirect. This is used internally by the mro code to
112 keep track of method/mro cache invalidations.
114 Currently, this list only grows, it never shrinks. This
115 was a performance consideration (properly tracking and
116 deleting isarev entries when someone removes an entry
117 from an C<@ISA> is costly, and it doesn't happen often
118 anyways). The fact that a class which no longer truly
119 "isa" this class at runtime remains on the list should be
120 considered a quirky implementation detail which is subject
121 to future change. It shouldn't be an issue as long as
122 you're looking at this list for the same reasons the
123 core code does: as a performance optimization
124 over having to search every class in existence.
126 As with C<mro::get_mro> above, C<UNIVERSAL> is special.
127 C<UNIVERSAL> (and parents') isarev lists do not include
128 every class in existence, even though all classes are
129 effectively descendants for method inheritance purposes.
131 =head2 mro::is_universal
135 Returns a boolean status indicating whether or not
136 the given classname is either C<UNIVERSAL> itself,
137 or one of C<UNIVERSAL>'s parents by C<@ISA> inheritance.
139 Any class for which this function returns true is
140 "universal" in the sense that all classes potentially
141 inherit methods from it.
143 For similar reasons to C<isarev> above, this flag is
144 permanent. Once it is set, it does not go away, even
145 if the class in question really isn't universal anymore.
147 =head2 mro::get_global_sub_generation
151 Returns the current value of C<PL_sub_generation>.
153 =head2 mro::invalidate_all_method_caches
157 Increments C<PL_sub_generation>, which invalidates method
158 caching in all packages.
160 =head2 mro::get_sub_generation
164 Returns the current value of a given package's C<sub_generation>.
165 This is only incremented when necessary for that package.
167 If one is trying to determine whether significant (method/cache-
168 affecting) changes have occured for a given stash since you last
169 checked, you should check both this and the global one above.
171 =head2 mro::method_changed_in
175 Invalidates the method cache of any classes dependant on the
180 This is somewhat like C<SUPER>, but it uses the C3 method
181 resolution order to get better consistency in multiple
182 inheritance situations. Note that while inheritance in
183 general follows whichever MRO is in effect for the
184 given class, C<next::method> only uses the C3 MRO.
186 One generally uses it like so:
191 my $superclass_answer = $self->next::method(@_);
192 return $superclass_answer + 1;
195 Note that you don't (re-)specify the method name.
196 It forces you to always use the same method name
197 as the method you started in.
199 It can be called on an object or a class, of course.
201 The way it resolves which actual method to call is:
203 1) First, it determines the linearized C3 MRO of
204 the object or class it is being called on.
206 2) Then, it determines the class and method name
207 of the context it was invoked from.
209 3) Finally, it searches down the C3 MRO list until
210 it reaches the contextually enclosing class, then
211 searches further down the MRO list for the next
212 method with the same name as the contextually
215 Failure to find a next method will result in an
216 exception being thrown (see below for alternatives).
218 This is substantially different than the behavior
219 of C<SUPER> under complex multiple inheritance,
220 (this becomes obvious when one realizes that the
221 common superclasses in the C3 linearizations of
222 a given class and one of its parents will not
223 always be ordered the same for both).
225 Caveat - Calling C<next::method> from methods defined outside the class:
227 There is an edge case when using C<next::method> from within a subroutine which was created in a different module than the one it is called from. It sounds complicated, but it really isn't. Here is an example which will not work correctly:
229 *Foo::foo = sub { (shift)->next::method(@_) };
231 The problem exists because the anonymous subroutine being assigned to the glob C<*Foo::foo> will show up in the call stack as being called C<__ANON__> and not C<foo> as you might expect. Since C<next::method> uses C<caller> to find the name of the method it was called in, it will fail in this case.
233 But fear not, there is a simple solution. The module C<Sub::Name> will reach into the perl internals and assign a name to an anonymous subroutine for you. Simply do this:
235 use Sub::Name 'subname';
236 *Foo::foo = subname 'Foo::foo' => sub { (shift)->next::method(@_) };
238 and things will Just Work.
242 Like C<next::method>, but just returns either
243 a code reference or C<undef> to indicate that
244 no further methods of this name exist.
246 =head2 maybe::next::method
248 In simple cases it is equivalent to:
250 $self->next::method(@_) if $self->next_can;
252 But there are some cases where only this solution
253 works (like "goto &maybe::next::method");
255 =head1 SEE ALSO - C3 Links
257 =head2 The original Dylan paper
261 =item L<http://www.webcom.com/haahr/dylan/linearization-oopsla96.html>
265 =head2 The prototype Perl 6 Object Model uses C3
269 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel/>
273 =head2 Parrot now uses C3
277 =item L<http://aspn.activestate.com/ASPN/Mail/Message/perl6-internals/2746631>
279 =item L<http://use.perl.org/~autrijus/journal/25768>
283 =head2 Python 2.3 MRO related links
287 =item L<http://www.python.org/2.3/mro.html>
289 =item L<http://www.python.org/2.2.2/descrintro.html#mro>
293 =head2 C3 for TinyCLOS
297 =item L<http://www.call-with-current-continuation.org/eggs/c3.html>
311 Brandon L. Black, E<lt>blblack@gmail.comE<gt>
313 Based on Stevan Little's L<Class::C3>