This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
B::walksymtable: clear cached methods
authorFather Chrysostomos <sprout@cpan.org>
Mon, 23 Oct 2017 16:50:10 +0000 (09:50 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 23 Oct 2017 16:52:02 +0000 (09:52 -0700)
There was a dummy assignment in B::walksymtable that I removed in com-
mit 6a4fc5265ba1 because it appeared to be redundant.  Removing that
assignment broke Module::Info (rt.cpan.org #123352), because it
changed the behaviour of B::Utils (by changing the behaviour of
B::walksymtable).  That seemingly useless assignment was actually
clearing cached methods, so that any B::GV object passed to the call-
back method sees ->CV pointing to something only if there is a real
sub there.  Since this seems like a reasonable expectation, this com-
mit restores the old behaviour, with a comment explaining what the
assignment is for, and tests it.

ext/B/B.pm
ext/B/t/b.t

index 3365a14..77cbaf4 100644 (file)
@@ -261,6 +261,8 @@ sub walksymtable {
     no strict 'refs';
     $prefix = '' unless defined $prefix;
     foreach my $sym ( sort keys %$symref ) {
+        my $dummy = $symref->{$sym}; # Copying the glob and incrementing
+                                     # the GPs refcnt clears cached methods
         $fullname = "*main::".$prefix.$sym;
        if ($sym =~ /::$/) {
            $sym = $prefix . $sym;
index a5d7249..587c8e6 100644 (file)
@@ -56,6 +56,21 @@ ok( join('', sort @syms) eq join('', sort keys %Subs), 'all symbols found' );
 # Make sure we only hit them each once.
 ok( (!grep $_ != 1, values %Subs), '...and found once' );
 
+
+# Make sure method caches are not present when walking the sym tab
+@Testing::Method::Caches::Foo::ISA='Testing::Method::Caches::Bar';
+sub Testing::Method::Caches::Bar::foo{}
+Testing::Method::Caches::Foo->foo; # caches the sub in the *foo glob
+
+my $have_cv;
+sub B::GV::method_cache_test { ${shift->CV} and ++$have_cv }
+
+B::walksymtable(\%Testing::Method::Caches::, 'method_cache_test',
+                 sub { 1 }, 'Testing::Method::Caches::');
+# $have_cv should only have been incremented for ::Bar::foo
+is $have_cv, 1, 'walksymtable clears cached methods';
+
+
 # Tests for MAGIC / MOREMAGIC
 ok( B::svref_2object(\$.)->MAGIC->TYPE eq "\0", '$. has \0 magic' );
 {