1Class::C3(3) User Contributed Perl Documentation Class::C3(3)
2
3
4
6 Class::C3 - A pragma to use the C3 method resolution order algortihm
7
9 package A;
10 use Class::C3;
11 sub hello { 'A::hello' }
12
13 package B;
14 use base 'A';
15 use Class::C3;
16
17 package C;
18 use base 'A';
19 use Class::C3;
20
21 sub hello { 'C::hello' }
22
23 package D;
24 use base ('B', 'C');
25 use Class::C3;
26
27 # Classic Diamond MI pattern
28 # <A>
29 # / \
30 # <B> <C>
31 # \ /
32 # <D>
33
34 package main;
35
36 # initializez the C3 module
37 # (formerly called in INIT)
38 Class::C3::initialize();
39
40 print join ', ' => Class::C3::calculateMRO('Diamond_D') # prints D, B, C, A
41
42 print D->hello() # prints 'C::hello' instead of the standard p5 'A::hello'
43
44 D->can('hello')->(); # can() also works correctly
45 UNIVERSAL::can('D', 'hello'); # as does UNIVERSAL::can()
46
48 This is pragma to change Perl 5's standard method resolution order from
49 depth-first left-to-right (a.k.a - pre-order) to the more sophisticated
50 C3 method resolution order.
51
52 What is C3?
53
54 C3 is the name of an algorithm which aims to provide a sane method res‐
55 olution order under multiple inheritence. It was first introduced in
56 the langauge Dylan (see links in the "SEE ALSO" section), and then
57 later adopted as the prefered MRO (Method Resolution Order) for the
58 new-style classes in Python 2.3. Most recently it has been adopted as
59 the 'canonical' MRO for Perl 6 classes, and the default MRO for Parrot
60 objects as well.
61
62 How does C3 work.
63
64 C3 works by always preserving local precendence ordering. This essen‐
65 tially means that no class will appear before any of it's subclasses.
66 Take the classic diamond inheritence pattern for instance:
67
68 <A>
69 / \
70 <B> <C>
71 \ /
72 <D>
73
74 The standard Perl 5 MRO would be (D, B, A, C). The result being that A
75 appears before C, even though C is the subclass of A. The C3 MRO algo‐
76 rithm however, produces the following MRO (D, B, C, A), which does not
77 have this same issue.
78
79 This example is fairly trival, for more complex examples and a deeper
80 explaination, see the links in the "SEE ALSO" section.
81
82 How does this module work?
83
84 This module uses a technique similar to Perl 5's method caching. When
85 "Class::C3::initialize" is called, this module calculates the MRO of
86 all the classes which called "use Class::C3". It then gathers informa‐
87 tion from the symbol tables of each of those classes, and builds a set
88 of method aliases for the correct dispatch ordering. Once all these
89 C3-based method tables are created, it then adds the method aliases
90 into the local classes symbol table.
91
92 The end result is actually classes with pre-cached method dispatch.
93 However, this caching does not do well if you start changing your @ISA
94 or messing with class symbol tables, so you should consider your
95 classes to be effectively closed. See the CAVEATS section for more
96 details.
97
99 This release also includes an optional module c3 in the opt/ folder. I
100 did not include this in the regular install since lowercase module
101 names are considered "bad" by some people. However I think that code
102 looks much nicer like this:
103
104 package MyClass;
105 use c3;
106
107 The the more clunky:
108
109 package MyClass;
110 use Class::C3;
111
112 But hey, it's your choice, thats why it is optional.
113
115 calculateMRO ($class)
116 Given a $class this will return an array of class names in the
117 proper C3 method resolution order.
118
119 initialize
120 This must be called to initalize the C3 method dispatch tables,
121 this module will not work if you do not do this. It is advised to
122 do this as soon as possible after loading any classes which use C3.
123 Here is a quick code example:
124
125 package Foo;
126 use Class::C3;
127 # ... Foo methods here
128
129 package Bar;
130 use Class::C3;
131 use base 'Foo';
132 # ... Bar methods here
133
134 package main;
135
136 Class::C3::initialize(); # now it is safe to use Foo and Bar
137
138 This function used to be called automatically for you in the INIT
139 phase of the perl compiler, but that lead to warnings if this mod‐
140 ule was required at runtime. After discussion with my user base
141 (the DBIx::Class folks), we decided that calling this in INIT was
142 more of an annoyance than a convience. I apologize to anyone this
143 causes problems for (although i would very suprised if I had any
144 other users other than the DBIx::Class folks). The simplest solu‐
145 tion of course is to define your own INIT method which calls this
146 function.
147
148 NOTE:
149
150 If "initialize" detects that "initialize" has already been exe‐
151 cuted, it will "uninitialize" and clear the MRO cache first.
152
153 uninitialize
154 Calling this function results in the removal of all cached methods,
155 and the restoration of the old Perl 5 style dispatch order
156 (depth-first, left-to-right).
157
158 reinitialize
159 This is an alias for "initialize" above.
160
162 It is always useful to be able to re-dispatch your method call to the
163 "next most applicable method". This module provides a pseudo package
164 along the lines of "SUPER::" or "NEXT::" which will re-dispatch the
165 method along the C3 linearization. This is best show with an examples.
166
167 # a classic diamond MI pattern ...
168 <A>
169 / \
170 <B> <C>
171 \ /
172 <D>
173
174 package A;
175 use c3;
176 sub foo { 'A::foo' }
177
178 package B;
179 use base 'A';
180 use c3;
181 sub foo { 'B::foo => ' . (shift)->next::method() }
182
183 package B;
184 use base 'A';
185 use c3;
186 sub foo { 'C::foo => ' . (shift)->next::method() }
187
188 package D;
189 use base ('B', 'C');
190 use c3;
191 sub foo { 'D::foo => ' . (shift)->next::method() }
192
193 print D->foo; # prints out "D::foo => B::foo => C::foo => A::foo"
194
195 A few things to note. First, we do not require you to add on the method
196 name to the "next::method" call (this is unlike "NEXT::" and "SUPER::"
197 which do require that). This helps to enforce the rule that you cannot
198 dispatch to a method of a different name (this is how "NEXT::" behaves
199 as well).
200
201 The next thing to keep in mind is that you will need to pass all argu‐
202 ments to "next::method" it can not automatically use the current @_.
203
204 If "next::method" cannot find a next method to re-dispatch the call to,
205 it will throw an exception. You can use "next::can" to see if
206 "next::method" will succeed before you call it like so:
207
208 $self->next::method(@_) if $self->next::can;
209
210 Additionally, you can use "maybe::next::method" as a shortcut to only
211 call the next method if it exists. The previous example could be sim‐
212 ply written as:
213
214 $self->maybe::next::method(@_);
215
216 There are some caveats about using "next::method", see below for those.
217
219 This module used to be labeled as experimental, however it has now been
220 pretty heavily tested by the good folks over at DBIx::Class and I am
221 confident this module is perfectly usable for whatever your needs might
222 be.
223
224 But there are still caveats, so here goes ...
225
226 Use of "SUPER::".
227 The idea of "SUPER::" under multiple inheritence is ambigious, and
228 generally not recomended anyway. However, it's use in conjuntion
229 with this module is very much not recommended, and in fact very
230 discouraged. The recommended approach is to instead use the sup‐
231 plied "next::method" feature, see more details on it's usage above.
232
233 Changing @ISA.
234 It is the author's opinion that changing @ISA at runtime is pure
235 insanity anyway. However, people do it, so I must caveat. Any
236 changes to the @ISA will not be reflected in the MRO calculated by
237 this module, and therefor probably won't even show up. If you do
238 this, you will need to call "reinitialize" in order to recalulate
239 all method dispatch tables. See the "reinitialize" documentation
240 and an example in t/20_reinitialize.t for more information.
241
242 Adding/deleting methods from class symbol tables.
243 This module calculates the MRO for each requested class by intero‐
244 gatting the symbol tables of said classes. So any symbol table
245 manipulation which takes place after our INIT phase is run will not
246 be reflected in the calculated MRO. Just as with changing the @ISA,
247 you will need to call "reinitialize" for any changes you make to
248 take effect.
249
250 Calling "next::method" from methods defined outside the class
251 There is an edge case when using "next::method" from within a sub‐
252 routine which was created in a different module than the one it is
253 called from. It sounds complicated, but it really isn't. Here is an
254 example which will not work correctly:
255
256 *Foo::foo = sub { (shift)->next::method(@_) };
257
258 The problem exists because the anonymous subroutine being assigned
259 to the glob *Foo::foo will show up in the call stack as being
260 called "__ANON__" and not "foo" as you might expect. Since
261 "next::method" uses "caller" to find the name of the method it was
262 called in, it will fail in this case.
263
264 But fear not, there is a simple solution. The module "Sub::Name"
265 will reach into the perl internals and assign a name to an anony‐
266 mous subroutine for you. Simply do this:
267
268 use Sub::Name 'subname';
269 *Foo::foo = subname 'Foo::foo' => sub { (shift)->next::method(@_) };
270
271 and things will Just Work. Of course this is not always possible to
272 do, but to be honest, I just can't manage to find a workaround for
273 it, so until someone gives me a working patch this will be a known
274 limitation of this module.
275
277 If your software requires Perl 5.9.5 or higher, you do not need
278 Class::C3, you can simply "use mro 'c3'", and not worry about "initial‐
279 ize()", avoid some of the above caveats, and get the best possible per‐
280 formance. See mro for more details.
281
282 If your software is meant to work on earlier Perls, use Class::C3 as
283 documented here. Class::C3 will detect Perl 5.9.5+ and take advantage
284 of the core support when available.
285
287 This module will load Class::C3::XS if it's installed and you are run‐
288 ning on a Perl version older than 5.9.5. Installing this is recom‐
289 mended when possible, as it results in significant performance improve‐
290 ments (but unlike the 5.9.5+ core support, it still has all of the same
291 caveats as Class::C3).
292
294 Devel::Cover was reporting 94.4% overall test coverage earlier in this
295 module's life. Currently, the test suite does things that break under
296 coverage testing, but it is fair to assume the coverage is still close
297 to that value.
298
300 The original Dylan paper
301
302 <http://www.webcom.com/haahr/dylan/linearization-oopsla96.html>
303
304 The prototype Perl 6 Object Model uses C3
305
306 <http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel/>
307
308 Parrot now uses C3
309
310 <http://aspn.activestate.com/ASPN/Mail/Message/perl6-internals/2746631>
311 <http://use.perl.org/~autrijus/journal/25768>
312
313 Python 2.3 MRO related links
314
315 <http://www.python.org/2.3/mro.html>
316 <http://www.python.org/2.2.2/descrintro.html#mro>
317
318 C3 for TinyCLOS
319
320 <http://www.call-with-current-continuation.org/eggs/c3.html>
321
323 Thanks to Matt S. Trout for using this module in his module DBIx::Class
324 and finding many bugs and providing fixes.
325 Thanks to Justin Guenther for making "next::method" more robust by han‐
326 dling calls inside "eval" and anon-subs.
327 Thanks to Robert Norris for adding support for "next::can" and
328 "maybe::next::method".
329
331 Stevan Little, <stevan@iinteractive.com>
332
333 Brandon L. Black, <blblack@gmail.com>
334
336 Copyright 2005, 2006 by Infinity Interactive, Inc.
337
338 <http://www.iinteractive.com>
339
340 This library is free software; you can redistribute it and/or modify it
341 under the same terms as Perl itself.
342
343
344
345perl v5.8.8 2007-05-03 Class::C3(3)