From: Brandon L Black Date: Tue, 19 Sep 2006 21:44:27 +0000 (+0000) Subject: version bump + potential fix for rt.cpan.org #12558 X-Git-Tag: 0.14~4 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FClass-C3.git;a=commitdiff_plain;h=ff168601b6fb63af7716f6da5c21e34053660f8a version bump + potential fix for rt.cpan.org #12558 --- diff --git a/ChangeLog b/ChangeLog index d461193..f2f2360 100644 --- 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 --- a/README +++ b/README @@ -1,4 +1,4 @@ -Class::C3 version 0.12 +Class::C3 version 0.14 =========================== INSTALLATION diff --git a/lib/Class/C3.pm b/lib/Class/C3.pm index 73e8228..c5a720c 100644 --- a/lib/Class/C3.pm +++ b/lib/Class/C3.pm @@ -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 folks). The simplest solution of c your own INIT method which calls this function. NOTE: -This can B be used to re-load the dispatch tables for all classes. Use C for that. + +If C detects that C has already been executed, it will L and +clear the MRO cache first. =item B @@ -367,11 +371,7 @@ style dispatch order (depth-first, left-to-right). =item B -This effectively calls C followed by C the result of which is a reloading of -B 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 above. =back diff --git a/t/23_multi_init.t b/t/23_multi_init.t new file mode 100644 index 0000000..ebe9a72 --- /dev/null +++ b/t/23_multi_init.t @@ -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');