7 # Is Class::C3 installed locally?
11 # Don't do anything if 5.9.5+
13 # Find out if we have Class::C3 at all
14 eval { require Class::C3 };
15 $C3_INSTALLED = 1 if !$@;
17 # Alias our private functions over to
19 *mro::import = \&__import;
20 *mro::get_linear_isa = \&__get_linear_isa;
21 *mro::set_mro = \&__set_mro;
22 *mro::get_mro = \&__get_mro;
23 *mro::get_isarev = \&__get_isarev;
24 *mro::is_universal = \&__is_universal;
25 *mro::method_changed_in = \&__method_changed_in;
26 *mro::invalidate_all_method_caches
27 = \&__invalidate_all_method_caches;
33 MRO::Compat - Partial mro::* interface compatibility for Perls < 5.9.5
37 package FooClass; use base qw/X Y Z/;
38 package X; use base qw/ZZZ/;
39 package Y; use base qw/ZZZ/;
40 package Z; use base qw/ZZZ/;
44 my $linear = mro::get_linear_isa('FooClass');
45 print join(q{, }, @$linear);
47 # Prints: "FooClass, X, ZZZ, Y, Z"
51 The "mro" namespace provides several utilities for dealing
52 with method resolution order and method caching in general
53 in Perl 5.9.5 and higher.
55 This module provides a subset of those interfaces for
56 earlier versions of Perl. It is a harmless no-op to use
57 it on 5.9.5+. If you're writing a piece of software
58 that would like to use the parts of 5.9.5+'s mro::
59 interfaces that are supported here, and you want
60 compatibility with older Perls, this is the module
63 This module never exports any functions. All calls must
64 be fully qualified with the C<mro::> prefix.
68 =head2 mro::get_linear_isa($classname[, $type])
70 Returns an arrayref which is the linearized MRO of the given class.
71 Uses whichever MRO is currently in effect for that class by default,
72 or the given MRO (either C<c3> or C<dfs> if specified as C<$type>).
74 The linearized MRO of a class is a single ordered list of all of the
75 classes that would be visited in the process of resolving a method
76 on the given class, starting with itself. It does not include any
79 On pre-5.9.5 Perls with MRO::Compat, explicitly asking for the C<c3>
80 MRO of a class will die if L<Class::C3> is not installed. If
81 L<Class::C3> is installed, it will detect C3 classes and return the
82 correct C3 MRO unless explicitly asked to return the C<dfs> MRO.
84 Note that C<UNIVERSAL> (and any members of C<UNIVERSAL>'s MRO) are not
85 part of the MRO of a class, even though all classes implicitly inherit
86 methods from C<UNIVERSAL> and its parents.
90 sub __get_linear_isa_dfs {
93 my $classname = shift;
95 my @lin = ($classname);
97 foreach my $parent (@{"$classname\::ISA"}) {
98 my $plin = __get_linear_isa_dfs($parent);
100 next if exists $stored{$_};
108 sub __get_linear_isa {
109 my ($classname, $type) = @_;
110 die "mro::get_mro requires a classname" if !$classname;
112 $type ||= __get_mro($classname);
114 return __get_linear_isa_dfs($classname);
116 elsif($type eq 'c3') {
117 return [Class::C3::calculateMRO($classname)];
119 die "type argument must be 'dfs' or 'c3'";
124 Not supported, and hence 5.9.5's "use mro 'foo'" is also not supported.
125 These will die if used on pre-5.9.5 Perls.
130 die q{The "use mro 'foo'" is only supported on Perl 5.9.5+};
133 =head2 mro::set_mro($classname, $type)
135 Not supported, will die if used on pre-5.9.5 Perls.
140 die q{mro::set_mro() is only supported on Perl 5.9.5+};
143 =head2 mro::get_mro($classname)
145 Returns the MRO of the given class (either C<c3> or C<dfs>).
150 my $classname = shift;
151 die "mro::get_mro requires a classname" if !$classname;
152 if($C3_INSTALLED && exists $Class::C3::MRO{$classname}) {
158 =head2 mro::get_isarev($classname)
160 Not supported, will die if used on pre-5.9.5 Perls.
165 die "mro::get_isarev() is only supported on Perl 5.9.5+";
168 =head2 mro::is_universal($classname)
170 Returns a boolean status indicating whether or not
171 the given classname is either C<UNIVERSAL> itself,
172 or one of C<UNIVERSAL>'s parents by C<@ISA> inheritance.
174 Any class for which this function returns true is
175 "universal" in the sense that all classes potentially
176 inherit methods from it.
181 my $classname = shift;
182 die "mro::is_universal requires a classname" if !$classname;
184 my $lin = __get_linear_isa($classname);
186 return 1 if $classname eq $_;
192 =head2 mro::invalidate_all_method_caches
194 Increments C<PL_sub_generation>, which invalidates method
195 caching in all packages.
199 sub __invalidate_all_method_caches {
200 # Super secret mystery code :)
201 @fedcba98::ISA = @fedcba98::ISA;
205 =head2 mro::method_changed_in($classname)
207 Invalidates the method cache of any classes dependent on the
208 given class. In L<MRO::Compat> on pre-5.9.5 Perls, this is
209 an alias for C<mro::invalidate_all_method_caches> above, as
210 pre-5.9.5 Perls have no other way to do this. It will still
211 enforce the requirement that you pass it a classname, for
216 sub __method_changed_in {
217 my $classname = shift;
218 die "mro::method_changed_in requires a classname" if !$classname;
220 __invalidate_all_method_caches();
231 Brandon L. Black, E<lt>blblack@gmail.comE<gt>
233 =head1 COPYRIGHT AND LICENSE
235 Copyright 2007 Brandon L. Black E<lt>blblack@gmail.comE<gt>
237 This library is free software; you can redistribute it and/or modify
238 it under the same terms as Perl itself.