Subject: | symbol table empty, but Foo:__ANON__ lives on |
Date: | Fri, 7 Jun 2019 23:20:16 -0400 |
To: | bug-Class-Unload [...] rt.cpan.org |
From: | Michael Hamlin <myrrhlin [...] gmail.com> |
howdy,
first, thank you for your contributions to cpan, particularly in the
DBIx:Class realm !
I was writing tests for a module's heavily customized import behavior, and
tried using Class::Unload to remove it from memory and "use" it again with
different parameters in subsequent tests. However, some symbols remained
defined and usable even after clearing the symbol table -- function symbols
created with typeglobs. They are somehow not in the symbol table for that
package, and yet have the same names...
I came up with this reduced example.
$ perl -MClass::Unload -MFoo -MDDP -E'
p %Foo::;say Foo::darn();
Class::Unload->unload("Foo");
p%Foo::;say Foo::darn()'
{
__ANON__ *Foo::__ANON__ (layers: ),
AUTOLOAD *Foo::AUTOLOAD (layers: ),
BEGIN *Foo::BEGIN (layers: ),
carp *Foo::carp (layers: ),
confess *Foo::confess (layers: ),
croak *Foo::croak (layers: ),
darn *Foo::darn (layers: ),
import *Foo::import (layers: ),
packagevar *Foo::packagevar (layers: )
}
defined sub Foo::darn
yep
{}
yeq
$ cat Foo.pm
package Foo;
our $AUTOLOAD;
our $packagevar = 'yep';
sub AUTOLOAD {
my $sub = *{"$AUTOLOAD"} = sub {return $packagevar++};
print "defined sub $AUTOLOAD\n";
return $sub->();
}
1;
This is a weird one, I'm not certain what's going on here -- kind of
voodoo, to me. It makes sense to me that there's a closure around the
variable, and so it lives on in anonymity, but how is it possible to still
refer to the closure by the package name after the symbol table is cleared?
I contrived a case to make the closure Carp::confess in the second call,
and confess reports the stacktrace begins with Foo::__ANON__()
which is doubly strange because 1) the Foo symbols table is empty, no
__ANON__ left in it, and 2) the source code is calling it by name
"Foo::darn".
Is there any way to find this closure and unload it after all? (the
finding part would be the trick...)
Perhaps this one should better go on stack overflow. Thanks for looking,
sir!
michael
PS. this is system perl on CentOS Linux release 7.5.1804 (Core
$ perl -v
This is perl 5, version 16, subversion 3 (v5.16.3) built for
x86_64-linux-thread-multi
(with 33 registered patches, see perl -V for more detail)