Flush the MRO cache at the end, rather than the start.
authorNicholas Clark <nick@ccl4.org>
Tue, 18 Aug 2009 11:03:15 +0000 (12:03 +0100)
committerNicholas Clark <nick@ccl4.org>
Tue, 18 Aug 2009 11:03:15 +0000 (12:03 +0100)
Vincent notes that doing it at the start is fragile, as it assumes that the
flush doesn't actively build any new caches, merely clear existing caches.
Right now the flush only clears, but why rely on it when not doing so is easy?

lib/constant.pm

index 255aa99..69f16c5 100644 (file)
@@ -45,7 +45,7 @@ sub import {
     my $constants;
     my $multiple  = ref $_[0];
     my $pkg = caller;
-    my $done_mro;
+    my $flush_mro;
     my $symtab;
 
     if (_CAN_PCS) {
@@ -124,8 +124,7 @@ sub import {
                    # constants from cv_const_sv are read only. So we have to:
                    Internals::SvREADONLY($scalar, 1);
                    $symtab->{$name} = \$scalar;
-                   # No need to flush the cache if we've just flushed it.
-                   mro::method_changed_in($pkg) unless $done_mro++;
+                   ++$flush_mro;
                } else {
                    *$full_name = sub () { $scalar };
                }
@@ -137,6 +136,8 @@ sub import {
            }
        }
     }
+    # Flush the cache exactly once if we make any direct symbol table changes.
+    mro::method_changed_in($pkg) if $flush_mro++;
 }
 
 1;