more consting
[p5sagit/p5-mst-13.2.git] / lib / mro.pm
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 possible CPAN mro dist
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 1;
21
22 __END__
23
24 =head1 NAME
25
26 mro - 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
35 The "mro" namespace provides several utilities for dealing
36 with method resolution order and method caching in general.
37
38 =head1 OVERVIEW
39
40 It's possible to change the MRO of a given class either by using C<use
41 mro> as shown in the synopsis, or by using the L</mro::set_mro> function
42 below.  The functions do not require loading the C<mro> module, as they
43 are actually provided by the core perl interpreter.  The C<use mro> syntax
44 is just syntactic sugar for setting the current package's MRO.
45
46 =head1 The C3 MRO
47
48 In addition to the traditional Perl default MRO (depth first
49 search, called C<DFS> here), Perl now offers the C3 MRO as
50 well.  Perl's support for C3 is based on the work done in
51 Stevan Little's module L<Class::C3>, and most of the C3-related
52 documentation here is ripped directly from there.
53
54 =head2 What is C3?
55
56 C3 is the name of an algorithm which aims to provide a sane method
57 resolution order under multiple inheritance. It was first introduced in
58 the language Dylan (see links in the L</"SEE ALSO"> section), and then
59 later adopted as the preferred MRO (Method Resolution Order) for the
60 new-style classes in Python 2.3. Most recently it has been adopted as the
61 "canonical" MRO for Perl 6 classes, and the default MRO for Parrot objects
62 as well.
63
64 =head2 How does C3 work
65
66 C3 works by always preserving local precendence ordering. This essentially
67 means that no class will appear before any of its subclasses. Take, for
68 instance, the classic diamond inheritance pattern:
69
70      <A>
71     /   \
72   <B>   <C>
73     \   /
74      <D>
75
76 The standard Perl 5 MRO would be (D, B, A, C). The result being that B<A>
77 appears before B<C>, even though B<C> is the subclass of B<A>. The C3 MRO
78 algorithm however, produces the following order: (D, B, C, A), which does
79 not have this issue.
80
81 This example is fairly trivial; for more complex cases and a deeper
82 explanation, see the links in the L</"SEE ALSO"> section.
83
84 =head1 Functions
85
86 =head2 mro::get_linear_isa($classname[, $type])
87
88 Returns an arrayref which is the linearized MRO of the given class.
89 Uses whichever MRO is currently in effect for that class by default,
90 or the given MRO (either C<c3> or C<dfs> if specified as C<$type>).
91
92 Note that C<UNIVERSAL> (and any members of C<UNIVERSAL>'s MRO) are not
93 part of the MRO of a class, even though all classes implicitly inherit
94 methods from C<UNIVERSAL> and its parents.
95
96 =head2 mro::set_mro($classname, $type)
97
98 Sets the MRO of the given class to the C<$type> argument (either
99 C<c3> or C<dfs>).
100
101 =head2 mro::get_mro($classname)
102
103 Returns the MRO of the given class (either C<c3> or C<dfs>).
104
105 =head2 mro::get_isarev($classname)
106
107 Gets the C<mro_isarev> for this class, returned as an
108 array of class names.  These are every class that "isa"
109 the given class name, even if the isa relationship is
110 indirect.  This is used internally by the MRO code to
111 keep track of method/MRO cache invalidations.
112
113 Currently, this list only grows, it never shrinks.  This
114 was a performance consideration (properly tracking and
115 deleting isarev entries when someone removes an entry
116 from an C<@ISA> is costly, and it doesn't happen often
117 anyways).  The fact that a class which no longer truly
118 "isa" this class at runtime remains on the list should be
119 considered a quirky implementation detail which is subject
120 to future change.  It shouldn't be an issue as long as
121 you're looking at this list for the same reasons the
122 core code does: as a performance optimization
123 over having to search every class in existence.
124
125 As with C<mro::get_mro> above, C<UNIVERSAL> is special.
126 C<UNIVERSAL> (and parents') isarev lists do not include
127 every class in existence, even though all classes are
128 effectively descendants for method inheritance purposes.
129
130 =head2 mro::is_universal($classname)
131
132 Returns a boolean status indicating whether or not
133 the given classname is either C<UNIVERSAL> itself,
134 or one of C<UNIVERSAL>'s parents by C<@ISA> inheritance.
135
136 Any class for which this function returns true is
137 "universal" in the sense that all classes potentially
138 inherit methods from it.
139
140 For similar reasons to C<isarev> above, this flag is
141 permanent.  Once it is set, it does not go away, even
142 if the class in question really isn't universal anymore.
143
144 =head2 mro::invalidate_all_method_caches()
145
146 Increments C<PL_sub_generation>, which invalidates method
147 caching in all packages.
148
149 =head2 mro::method_changed_in($classname)
150
151 Invalidates the method cache of any classes dependent on the
152 given class.
153
154 =head2 next::method
155
156 This is somewhat like C<SUPER>, but it uses the C3 method
157 resolution order to get better consistency in multiple
158 inheritance situations.  Note that while inheritance in
159 general follows whichever MRO is in effect for the
160 given class, C<next::method> only uses the C3 MRO.
161
162 One generally uses it like so:
163
164   sub some_method {
165     my $self = shift;
166     my $superclass_answer = $self->next::method(@_);
167     return $superclass_answer + 1;
168   }
169
170 Note that you don't (re-)specify the method name.
171 It forces you to always use the same method name
172 as the method you started in.
173
174 It can be called on an object or a class, of course.
175
176 The way it resolves which actual method to call is:
177
178 =over 4
179
180 =item 1
181
182 First, it determines the linearized C3 MRO of
183 the object or class it is being called on.
184
185 =item 2
186
187 Then, it determines the class and method name
188 of the context it was invoked from.
189
190 =item 3
191
192 Finally, it searches down the C3 MRO list until
193 it reaches the contextually enclosing class, then
194 searches further down the MRO list for the next
195 method with the same name as the contextually
196 enclosing method.
197
198 =back
199
200 Failure to find a next method will result in an
201 exception being thrown (see below for alternatives).
202
203 This is substantially different than the behavior
204 of C<SUPER> under complex multiple inheritance.
205 (This becomes obvious when one realizes that the
206 common superclasses in the C3 linearizations of
207 a given class and one of its parents will not
208 always be ordered the same for both.)
209
210 B<Caveat>: Calling C<next::method> from methods defined outside the class:
211
212 There is an edge case when using C<next::method> from within a subroutine
213 which was created in a different module than the one it is called from. It
214 sounds complicated, but it really isn't. Here is an example which will not
215 work correctly:
216
217   *Foo::foo = sub { (shift)->next::method(@_) };
218
219 The problem exists because the anonymous subroutine being assigned to the
220 C<*Foo::foo> glob will show up in the call stack as being called
221 C<__ANON__> and not C<foo> as you might expect. Since C<next::method> uses
222 C<caller> to find the name of the method it was called in, it will fail in
223 this case. 
224
225 But fear not, there's a simple solution. The module C<Sub::Name> will
226 reach into the perl internals and assign a name to an anonymous subroutine
227 for you. Simply do this:
228
229   use Sub::Name 'subname';
230   *Foo::foo = subname 'Foo::foo' => sub { (shift)->next::method(@_) };
231
232 and things will Just Work.
233
234 =head2 next::can
235
236 This is similar to C<next::method>, but just returns either a code
237 reference or C<undef> to indicate that no further methods of this name
238 exist.
239
240 =head2 maybe::next::method
241
242 In simple cases, it is equivalent to:
243
244    $self->next::method(@_) if $self->next_can;
245
246 But there are some cases where only this solution
247 works (like C<goto &maybe::next::method>);
248
249 =head1 PERFORMANCE CONSIDERATIONS
250
251 Specifying the mro type of a class before setting C<@ISA> will
252 be faster than the other way around.  Also, making all of your
253 C<@ISA> manipulations in a single assignment statement will be
254 faster that doing them one by one via C<push> (which is what
255 C<use base> does currently).
256
257 Examples:
258
259   # The slowest way
260   package Foo;
261   use base qw/A B C/;
262   use mro 'c3';
263
264   # The fastest way
265   # (not exactly equivalent to above,
266   #   as base.pm can do other magic)
267   use mro 'c3';
268   use A ();
269   use B ();
270   use C ();
271   our @ISA = qw/A B C/;
272
273 Generally speaking, every time C<@ISA> is modified, the MRO
274 of that class will be recalculated, because of the way array
275 magic works.  Pushing multiple items onto C<@ISA> in one push
276 statement still counts as multiple modifications.  However,
277 assigning a list to C<@ISA> only counts as a single
278 modification.  Thus if you really need to do C<push> as
279 opposed to assignment, C<@ISA = (@ISA, qw/A B C/);>
280 will still be faster than C<push(@ISA, qw/A B C/);>
281
282 =head1 SEE ALSO
283
284 =head2 The original Dylan paper
285
286 =over 4
287
288 =item L<http://www.webcom.com/haahr/dylan/linearization-oopsla96.html>
289
290 =back
291
292 =head2 The prototype Perl 6 Object Model uses C3
293
294 =over 4
295
296 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel/>
297
298 =back
299
300 =head2 Parrot now uses C3
301
302 =over 4
303
304 =item L<http://aspn.activestate.com/ASPN/Mail/Message/perl6-internals/2746631>
305
306 =item L<http://use.perl.org/~autrijus/journal/25768>
307
308 =back
309
310 =head2 Python 2.3 MRO related links
311
312 =over 4
313
314 =item L<http://www.python.org/2.3/mro.html>
315
316 =item L<http://www.python.org/2.2.2/descrintro.html#mro>
317
318 =back
319
320 =head2 C3 for TinyCLOS
321
322 =over 4
323
324 =item L<http://www.call-with-current-continuation.org/eggs/c3.html>
325
326 =back 
327
328 =head2 Class::C3
329
330 =over 4
331
332 =item L<Class::C3>
333
334 =back
335
336 =head1 AUTHOR
337
338 Brandon L. Black, E<lt>blblack@gmail.comE<gt>
339
340 Based on Stevan Little's L<Class::C3>
341
342 =cut