This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: new C3 MRO patch
[perl5.git] / lib / mro.pm
CommitLineData
e1a479c5
BB
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#
8package mro;
9use strict;
10use warnings;
11
12# mro.pm versions < 1.00 reserved for possible CPAN mro dist
13# (for partial back-compat to 5.[68].x)
14our $VERSION = '1.00';
15
16sub import {
17 mro::set_mro(scalar(caller), $_[1]) if $_[1];
18}
19
201;
21
22__END__
23
24=head1 NAME
25
26mro - Method Resolution Order
27
28=head1 SYNOPSIS
29
30 use mro 'dfs'; # enable DFS mro for this class (Perl default)
31 use mro 'c3'; # enable C3 mro for this class
32
33=head1 DESCRIPTION
34
35The "mro" namespace provides several utilities for dealing
36with method resolution order and method caching in general.
37
38=head1 OVERVIEW
39
40One can change the mro of a given class by either C<use mro>
41as shown in the synopsis, or by using the L</mro::set_mro>
42function below. The functions below do not require that one
43loads the "mro" module, they are provided by the core. The
44C<use mro> syntax is just syntax sugar for setting the current
45package's mro.
46
47=head1 The C3 MRO
48
49In addition to the traditional Perl default MRO (depth first
50search, called C<dfs> here), Perl now offers the C3 MRO as
51well. Perl's support for C3 is based on the work done in
52Stevan Little's L<Class::C3>, and most of the C3-related
53documentation here is ripped directly from there.
54
55=head2 What is C3?
56
57C3 is the name of an algorithm which aims to provide a sane method resolution order under multiple
58inheritence. It was first introduced in the langauge Dylan (see links in the L<SEE ALSO> section),
59and then later adopted as the prefered MRO (Method Resolution Order) for the new-style classes in
60Python 2.3. Most recently it has been adopted as the 'canonical' MRO for Perl 6 classes, and the
61default MRO for Parrot objects as well.
62
63=head2 How does C3 work.
64
65C3 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:
66
67 <A>
68 / \
69 <B> <C>
70 \ /
71 <D>
72
73The 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.
74
75This example is fairly trival, for more complex examples and a deeper explaination, see the links in the L<SEE ALSO - C3 Links> section.
76
77=head1 Functions
78
79=head2 mro::get_linear_isa
80
81Arguments: classname[, type]
82
83Return an arrayref which is the linearized MRO of the given class.
84Uses whichever MRO is currently in effect for that class by default,
85or the given mro (either C<c3> or C<dfs> if specified as C<type>).
86
87C<UNIVERSAL> (and any members of C<UNIVERSAL>'s MRO) are not part
88of the MRO of a class, even though all classes implicitly inherit
89methods from C<UNIVERSAL> and its parents.
90
91=head2 mro::set_mro
92
93Arguments: classname, type
94
95Sets the MRO of the given class to the C<type> argument (either
96C<c3> or C<dfs>).
97
98=head2 mro::get_mro
99
100Arguments: classname
101
102Returns the MRO of the given class (either C<c3> or C<dfs>)
103
104=head2 mro::get_isarev
105
106Arguments: classname
107
108Gets the C<mro_isarev> for this class, returned as an
109array of classnames. These are every class that "isa"
110the given classname, even if the isa relationship is
111indirect. This is used internally by the mro code to
112keep track of method/mro cache invalidations.
113
114Currently, this list only grows, it never shrinks. This
115was a performance consideration (properly tracking and
116deleting isarev entries when someone removes an entry
117from an C<@ISA> is costly, and it doesn't happen often
118anyways). The fact that a class which no longer truly
119"isa" this class at runtime remains on the list should be
120considered a quirky implementation detail which is subject
121to future change. It shouldn't be an issue as long as
122you're looking at this list for the same reasons the
123core code does: as a performance optimization
124over having to search every class in existence.
125
126As with C<mro::get_mro> above, C<UNIVERSAL> is special.
127C<UNIVERSAL> (and parents') isarev lists do not include
128every class in existence, even though all classes are
129effectively descendants for method inheritance purposes.
130
131=head2 mro::is_universal
132
133Arguments: classname
134
135Returns a boolean status indicating whether or not
136the given classname is either C<UNIVERSAL> itself,
137or one of C<UNIVERSAL>'s parents by C<@ISA> inheritance.
138
139Any class for which this function returns true is
140"universal" in the sense that all classes potentially
141inherit methods from it.
142
143For similar reasons to C<isarev> above, this flag is
144permanent. Once it is set, it does not go away, even
145if the class in question really isn't universal anymore.
146
147=head2 mro::get_global_sub_generation
148
149Arguments: none
150
151Returns the current value of C<PL_sub_generation>.
152
153=head2 mro::invalidate_all_method_caches
154
155Arguments: none
156
157Increments C<PL_sub_generation>, which invalidates method
158caching in all packages.
159
160=head2 mro::get_sub_generation
161
162Arguments: classname
163
164Returns the current value of a given package's C<sub_generation>.
165This is only incremented when necessary for that package.
166
167If one is trying to determine whether significant (method/cache-
168affecting) changes have occured for a given stash since you last
169checked, you should check both this and the global one above.
170
171=head2 mro::method_changed_in
172
173Arguments: classname
174
175Invalidates the method cache of any classes dependant on the
176given class.
177
178=head2 next::method
179
180This is somewhat like C<SUPER>, but it uses the C3 method
181resolution order to get better consistency in multiple
182inheritance situations. Note that while inheritance in
183general follows whichever MRO is in effect for the
184given class, C<next::method> only uses the C3 MRO.
185
186One generally uses it like so:
187
188 sub some_method {
189 my $self = shift;
190
191 my $superclass_answer = $self->next::method(@_);
192 return $superclass_answer + 1;
193 }
194
195Note that you don't (re-)specify the method name.
196It forces you to always use the same method name
197as the method you started in.
198
199It can be called on an object or a class, of course.
200
201The way it resolves which actual method to call is:
202
2031) First, it determines the linearized C3 MRO of
204the object or class it is being called on.
205
2062) Then, it determines the class and method name
207of the context it was invoked from.
208
2093) Finally, it searches down the C3 MRO list until
210it reaches the contextually enclosing class, then
211searches further down the MRO list for the next
212method with the same name as the contextually
213enclosing method.
214
215Failure to find a next method will result in an
216exception being thrown (see below for alternatives).
217
218This is substantially different than the behavior
219of C<SUPER> under complex multiple inheritance,
220(this becomes obvious when one realizes that the
221common superclasses in the C3 linearizations of
222a given class and one of its parents will not
223always be ordered the same for both).
224
225Caveat - Calling C<next::method> from methods defined outside the class:
226
227There 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:
228
229 *Foo::foo = sub { (shift)->next::method(@_) };
230
231The 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.
232
233But 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:
234
235 use Sub::Name 'subname';
236 *Foo::foo = subname 'Foo::foo' => sub { (shift)->next::method(@_) };
237
238and things will Just Work.
239
240=head2 next::can
241
242Like C<next::method>, but just returns either
243a code reference or C<undef> to indicate that
244no further methods of this name exist.
245
246=head2 maybe::next::method
247
248In simple cases it is equivalent to:
249
250 $self->next::method(@_) if $self->next_can;
251
252But there are some cases where only this solution
253works (like "goto &maybe::next::method");
254
255=head1 SEE ALSO - C3 Links
256
257=head2 The original Dylan paper
258
259=over 4
260
261=item L<http://www.webcom.com/haahr/dylan/linearization-oopsla96.html>
262
263=back
264
265=head2 The prototype Perl 6 Object Model uses C3
266
267=over 4
268
269=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel/>
270
271=back
272
273=head2 Parrot now uses C3
274
275=over 4
276
277=item L<http://aspn.activestate.com/ASPN/Mail/Message/perl6-internals/2746631>
278
279=item L<http://use.perl.org/~autrijus/journal/25768>
280
281=back
282
283=head2 Python 2.3 MRO related links
284
285=over 4
286
287=item L<http://www.python.org/2.3/mro.html>
288
289=item L<http://www.python.org/2.2.2/descrintro.html#mro>
290
291=back
292
293=head2 C3 for TinyCLOS
294
295=over 4
296
297=item L<http://www.call-with-current-continuation.org/eggs/c3.html>
298
299=back
300
301=head2 Class::C3
302
303=over 4
304
305=item L<Class::C3>
306
307=back
308
309=head1 AUTHOR
310
311Brandon L. Black, E<lt>blblack@gmail.comE<gt>
312
313Based on Stevan Little's L<Class::C3>
314
315=cut