version bump + potential fix for rt.cpan.org #12558
Brandon L Black [Tue, 19 Sep 2006 21:44:27 +0000 (21:44 +0000)]
ChangeLog
README
lib/Class/C3.pm
t/23_multi_init.t [new file with mode: 0644]

index d461193..f2f2360 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 Revision history for Perl extension Class::C3.
 
+0.14 XXX Not Yet Released
+    - Fix for rt.cpan.org #21558
+
 0.13 Fri. Aug 25, 2006
     - Make use of Algorithm::C3 0.05's merge caching
 
diff --git a/README b/README
index 0b51f8e..d93cfe8 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-Class::C3 version 0.12
+Class::C3 version 0.14
 ===========================
 
 INSTALLATION
index 73e8228..c5a720c 100644 (file)
@@ -7,7 +7,7 @@ use warnings;
 use Scalar::Util 'blessed';
 use Algorithm::C3;
 
-our $VERSION = '0.13';
+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,14 +61,10 @@ 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
 
@@ -358,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>
 
@@ -367,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
 
diff --git a/t/23_multi_init.t b/t/23_multi_init.t
new file mode 100644 (file)
index 0000000..ebe9a72
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 2;
+
+BEGIN {
+    use_ok('Class::C3');
+}
+
+=pod
+
+rt.cpan.org # 21558
+
+If compile-time code from another module issues a [re]initialize() part-way
+through the process of setting up own our modules, that shouldn't prevent
+our own initialize() call from working properly.
+
+=cut
+
+{
+    package TestMRO::A;
+    use Class::C3;
+    sub testmethod { 42 }
+
+    package TestMRO::B;
+    use base 'TestMRO::A';
+    use Class::C3;
+
+    package TestMRO::C;
+    use base 'TestMRO::A';
+    use Class::C3;
+    sub testmethod { shift->next::method + 1 }
+
+    package TestMRO::D;
+    BEGIN { Class::C3::initialize }
+    use base 'TestMRO::B';
+    use base 'TestMRO::C';
+    use Class::C3;
+    sub new {
+        my $class = shift;
+        my $self = {};
+        bless $self => $class;
+    }
+}
+
+Class::C3::initialize;
+is(TestMRO::D->new->testmethod, 43, 'double-initialize works ok');