2 package # hide from PAUSE
11 our $VERSION = '0.03';
13 use base 'Class::MOP::Class';
15 my $_find_method = sub {
16 my ($class, $method) = @_;
17 foreach my $super ($class->class_precedence_list) {
18 return $super->meta->get_method($method)
19 if $super->meta->has_method($method);
23 C3MethodDispatchOrder->meta->add_around_method_modifier('initialize' => sub {
25 my $meta = $cont->(@_);
26 $meta->add_method('AUTOLOAD' => sub {
27 my $meta = $_[0]->meta;
31 my $label = ${$meta->name . '::AUTOLOAD'};
32 $method_name = (split /\:\:/ => $label)[-1];
34 my $method = $_find_method->($meta, $method_name);
35 (defined $method) || confess "Method ($method_name) not found";
37 }) unless $meta->has_method('AUTOLOAD');
38 $meta->add_method('can' => sub {
39 $_find_method->($_[0]->meta, $_[1]);
40 }) unless $meta->has_method('can');
47 $self->add_package_symbol('@SUPERS' => [])
48 unless $self->has_package_symbol('@SUPERS');
52 @{$self->get_package_symbol('@SUPERS')} = @supers;
54 @{$self->get_package_symbol('@SUPERS')};
57 sub class_precedence_list {
61 } Algorithm::C3::merge($self, sub {
63 map { $_->meta } $class->superclasses;
75 C3MethodDispatchOrder - An example attribute metaclass for changing to C3 method dispatch order
79 # a classic diamond inheritence graph
88 use metaclass 'C3MethodDispatchOrder';
90 sub hello { return "Hello from A" }
93 use metaclass 'C3MethodDispatchOrder';
94 B->meta->superclasses('A');
97 use metaclass 'C3MethodDispatchOrder';
98 C->meta->superclasses('A');
100 sub hello { return "Hello from C" }
103 use metaclass 'C3MethodDispatchOrder';
104 D->meta->superclasses('B', 'C');
106 print join ", " => D->meta->class_precedence_list; # prints C3 order D, B, C, A
108 # later in other code ...
110 print D->hello; # print 'Hello from C' instead of the normal 'Hello from A'
114 This is an example of how you could change the method dispatch order of a
115 class using L<Class::MOP>. Using the L<Algorithm::C3> module, this repleces
116 the normal depth-first left-to-right perl dispatch order with the C3 method
117 dispatch order (see the L<Algorithm::C3> or L<Class::C3> docs for more
118 information about this).
120 This example could be used as a template for other method dispatch orders
121 as well, all that is required is to write a the C<class_precedence_list> method
122 which will return a linearized list of classes to dispatch along.
126 Stevan Little E<lt>stevan@iinteractive.comE<gt>
128 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
130 =head1 COPYRIGHT AND LICENSE
132 Copyright 2006 by Infinity Interactive, Inc.
134 L<http://www.iinteractive.com>
136 This library is free software; you can redistribute it and/or modify
137 it under the same terms as Perl itself.