X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FClass%2FC3.pm;h=c5a720cbcc8cfb5283a52054908dec84171f127f;hb=ff168601b6fb63af7716f6da5c21e34053660f8a;hp=988a8e9643365aa828f3606f2aba4829a8ab57ad;hpb=fa91a1c74155c2a85026814dfeb203a2bf1b6124;p=gitmo%2FClass-C3.git diff --git a/lib/Class/C3.pm b/lib/Class/C3.pm index 988a8e9..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.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 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 @@ -366,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 @@ -552,6 +553,9 @@ and finding many bugs and providing fixes. =item Thanks to Justin Guenther for making C more robust by handling calls inside C and anon-subs. +=item Thanks to Robert Norris for adding support for C and +C. + =back =head1 AUTHOR @@ -567,4 +571,4 @@ L 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