version bump + potential fix for rt.cpan.org #12558
[gitmo/Class-C3.git] / lib / Class / C3.pm
index 988a8e9..c5a720c 100644 (file)
@@ -7,7 +7,7 @@ use warnings;
 use Scalar::Util 'blessed';
 use Algorithm::C3;
 
-our $VERSION = '0.12';
+our $VERSION = '0.14';
 
 # this is our global stash of both 
 # MRO's and method dispatch tables
@@ -28,6 +28,7 @@ our %MRO;
 # use these for debugging ...
 sub _dump_MRO_table { %MRO }
 our $TURN_OFF_C3 = 0;
+our $_initialized = 0;
 
 sub import {
     my $class = caller();
@@ -45,9 +46,14 @@ sub import {
 sub initialize {
     # why bother if we don't have anything ...
     return unless keys %MRO;
+    if($_initialized) {
+        uninitialize();
+        $MRO{$_} = undef foreach keys %MRO;
+    }
     _calculate_method_dispatch_tables();
     _apply_method_dispatch_tables();
     %next::METHOD_CACHE = ();
+    $_initialized = 1;
 }
 
 sub uninitialize {
@@ -55,27 +61,24 @@ sub uninitialize {
     return unless keys %MRO;    
     _remove_method_dispatch_tables();    
     %next::METHOD_CACHE = ();
+    $_initialized = 0;
 }
 
-sub reinitialize {
-    uninitialize();
-    # clean up the %MRO before we re-initialize
-    $MRO{$_} = undef foreach keys %MRO;
-    initialize();
-}
+sub reinitialize { goto &initialize }
 
 ## functions for applying C3 to classes
 
 sub _calculate_method_dispatch_tables {
+    my %merge_cache;
     foreach my $class (keys %MRO) {
-        _calculate_method_dispatch_table($class);
+        _calculate_method_dispatch_table($class, \%merge_cache);
     }
 }
 
 sub _calculate_method_dispatch_table {
-    my $class = shift;
+    my ($class, $merge_cache) = @_;
     no strict 'refs';
-    my @MRO = calculateMRO($class);
+    my @MRO = calculateMRO($class, $merge_cache);
     $MRO{$class} = { MRO => \@MRO };
     my $has_overload_fallback = 0;
     my %methods;
@@ -139,11 +142,11 @@ sub _remove_method_dispatch_table {
 ## functions for calculating C3 MRO
 
 sub calculateMRO {
-    my ($class) = @_;
+    my ($class, $merge_cache) = @_;
     return Algorithm::C3::merge($class, sub { 
         no strict 'refs'; 
         @{$_[0] . '::ISA'};
-    });
+    }, $merge_cache);
 }
 
 package  # hide me from PAUSE
@@ -357,7 +360,9 @@ any other users other than the L<DBIx::Class> folks). The simplest solution of c
 your own INIT method which calls this function. 
 
 NOTE: 
-This can B<not> be used to re-load the dispatch tables for all classes. Use C<reinitialize> for that.
+
+If C<initialize> detects that C<initialize> has already been executed, it will L</uninitialize> and
+clear the MRO cache first.
 
 =item B<uninitialize>
 
@@ -366,11 +371,7 @@ style dispatch order (depth-first, left-to-right).
 
 =item B<reinitialize>
 
-This effectively calls C<uninitialize> followed by C<initialize> the result of which is a reloading of
-B<all> the calculated C3 dispatch tables. 
-
-It should be noted that if you have a large class library, this could potentially be a rather costly 
-operation.
+This is an alias for L</initialize> above.
 
 =back
 
@@ -552,6 +553,9 @@ and finding many bugs and providing fixes.
 =item Thanks to Justin Guenther for making C<next::method> more robust by handling 
 calls inside C<eval> and anon-subs.
 
+=item Thanks to Robert Norris for adding support for C<next::can> and 
+C<maybe::next::method>.
+
 =back
 
 =head1 AUTHOR
@@ -567,4 +571,4 @@ L<http://www.iinteractive.com>
 This library is free software; you can redistribute it and/or modify
 it under the same terms as Perl itself. 
 
-=cut
\ No newline at end of file
+=cut