Commit | Line | Data |
---|---|---|
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 | # | |
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 | 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 | |
45 | package's mro. | |
46 | ||
47 | =head1 The C3 MRO | |
48 | ||
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. | |
54 | ||
55 | =head2 What is C3? | |
56 | ||
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. | |
62 | ||
63 | =head2 How does C3 work. | |
64 | ||
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: | |
66 | ||
67 | <A> | |
68 | / \ | |
69 | <B> <C> | |
70 | \ / | |
71 | <D> | |
72 | ||
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. | |
74 | ||
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. | |
76 | ||
77 | =head1 Functions | |
78 | ||
79 | =head2 mro::get_linear_isa | |
80 | ||
81 | Arguments: classname[, type] | |
82 | ||
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>). | |
86 | ||
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. | |
90 | ||
91 | =head2 mro::set_mro | |
92 | ||
93 | Arguments: classname, type | |
94 | ||
95 | Sets the MRO of the given class to the C<type> argument (either | |
96 | C<c3> or C<dfs>). | |
97 | ||
98 | =head2 mro::get_mro | |
99 | ||
100 | Arguments: classname | |
101 | ||
102 | Returns the MRO of the given class (either C<c3> or C<dfs>) | |
103 | ||
104 | =head2 mro::get_isarev | |
105 | ||
106 | Arguments: classname | |
107 | ||
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. | |
113 | ||
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. | |
125 | ||
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. | |
130 | ||
131 | =head2 mro::is_universal | |
132 | ||
133 | Arguments: classname | |
134 | ||
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. | |
138 | ||
139 | Any class for which this function returns true is | |
140 | "universal" in the sense that all classes potentially | |
141 | inherit methods from it. | |
142 | ||
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. | |
146 | ||
147 | =head2 mro::get_global_sub_generation | |
148 | ||
149 | Arguments: none | |
150 | ||
151 | Returns the current value of C<PL_sub_generation>. | |
152 | ||
153 | =head2 mro::invalidate_all_method_caches | |
154 | ||
155 | Arguments: none | |
156 | ||
157 | Increments C<PL_sub_generation>, which invalidates method | |
158 | caching in all packages. | |
159 | ||
160 | =head2 mro::get_sub_generation | |
161 | ||
162 | Arguments: classname | |
163 | ||
164 | Returns the current value of a given package's C<sub_generation>. | |
165 | This is only incremented when necessary for that package. | |
166 | ||
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. | |
170 | ||
171 | =head2 mro::method_changed_in | |
172 | ||
173 | Arguments: classname | |
174 | ||
175 | Invalidates the method cache of any classes dependant on the | |
176 | given class. | |
177 | ||
178 | =head2 next::method | |
179 | ||
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. | |
185 | ||
186 | One 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 | ||
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. | |
198 | ||
199 | It can be called on an object or a class, of course. | |
200 | ||
201 | The way it resolves which actual method to call is: | |
202 | ||
203 | 1) First, it determines the linearized C3 MRO of | |
204 | the object or class it is being called on. | |
205 | ||
206 | 2) Then, it determines the class and method name | |
207 | of the context it was invoked from. | |
208 | ||
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 | |
213 | enclosing method. | |
214 | ||
215 | Failure to find a next method will result in an | |
216 | exception being thrown (see below for alternatives). | |
217 | ||
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). | |
224 | ||
225 | Caveat - Calling C<next::method> from methods defined outside the class: | |
226 | ||
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: | |
228 | ||
229 | *Foo::foo = sub { (shift)->next::method(@_) }; | |
230 | ||
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. | |
232 | ||
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: | |
234 | ||
235 | use Sub::Name 'subname'; | |
236 | *Foo::foo = subname 'Foo::foo' => sub { (shift)->next::method(@_) }; | |
237 | ||
238 | and things will Just Work. | |
239 | ||
240 | =head2 next::can | |
241 | ||
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. | |
245 | ||
246 | =head2 maybe::next::method | |
247 | ||
248 | In simple cases it is equivalent to: | |
249 | ||
250 | $self->next::method(@_) if $self->next_can; | |
251 | ||
252 | But there are some cases where only this solution | |
253 | works (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 | ||
311 | Brandon L. Black, E<lt>blblack@gmail.comE<gt> | |
312 | ||
313 | Based on Stevan Little's L<Class::C3> | |
314 | ||
315 | =cut |