Flush PL_stashcache on glob-to-glob assignment
authorFather Chrysostomos <sprout@cpan.org>
Sat, 8 Jun 2013 21:38:02 +0000 (14:38 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 9 Jun 2013 06:25:13 +0000 (23:25 -0700)
Commit dc93d7fb33f6b2093 says this:

    Flush PL_stashcache when assigning a file handle to a typeglob.

    File handles take priority over stashes for method dispatch.
    Assigning a file handle to a typeglob potentially creates a file
    handle where one did not exist before.  As PL_stashcache only con-
    tains entries for names which unambiguously resolve to stashes,
    such a change may mean that PL_stashcache now contains an invalid
    entry.  As it’s hard to work out exactly which entries might be
    affected, simply flush the entire cache and let it rebuild itself.

But it only applied to io-to-glob assignment.  This commit extends it
to glob-to-glob assignment.

sv.c
t/op/method.t

diff --git a/sv.c b/sv.c
index 8d1c015..962e392 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -3746,6 +3746,15 @@ S_glob_assign_glob(pTHX_ SV *const dstr, SV *const sstr, const int dtype)
            );
     }
     else if(mro_changes) mro_method_changed_in(GvSTASH(dstr));
+    if (GvIO(dstr) && dtype == SVt_PVGV) {
+       DEBUG_o(Perl_deb(aTHX_
+                       "glob_assign_glob clearing PL_stashcache\n"));
+       /* It's a cache. It will rebuild itself quite happily.
+          It's a lot of effort to work out exactly which key (or keys)
+          might be invalidated by the creation of the this file handle.
+        */
+       hv_clear(PL_stashcache);
+    }
     return;
 }
 
index 5ed8f76..27354ce 100644 (file)
@@ -13,7 +13,7 @@ BEGIN {
 use strict;
 no warnings 'once';
 
-plan(tests => 141);
+plan(tests => 142);
 
 @A::ISA = 'B';
 @B::ISA = 'C';
@@ -582,7 +582,7 @@ SKIP: {
 
     is(Colour::H1->getline(), <DATA>, 'read from a file');
     is(Color::H1->getline(), <DATA>,
-       'file handles take priority after typeglob assignment');
+       'file handles take priority after io-to-typeglob assignment');
 
     *Color::H1 = *CLOSED{IO};
     {
@@ -595,6 +595,11 @@ SKIP: {
     is(Color::H1->getline(), 'method in Color::H1',
        'undefining the typeglob does change object resolution');
 
+    *Color::H1 = *Colour::H1;
+
+    is(Color::H1->getline(), <DATA>,
+       'file handles take priority after typeglob-to-typeglob assignment');
+
     seek Colour::H1, $fh_start, Fcntl::SEEK_SET() or die $!;
     seek DATA, $data_start, Fcntl::SEEK_SET() or die $!;