I have come across the interesting problem of reloading a module.
There is Symbol::delete_package(), but if called to delete 'Foo::Bar', it will
delete $Foo::{Bar::} stash, effectively wiping along every Foo::Bar::* package.I need to be able to 'unload' package Foo::Bar, so I can reload it with the equivalent of eval "use Foo::Bar";
Here is the solution I came up with and I wanted to get some feedback on it.
Basically, instead of just wiping the child stash from the parent stash, I iterate over stash entries for that package, wiping everything that's not a substash (i.e. ending in '::').
I also unload the module with DynaLoader if it was an XS module so it will be reloaded on the second 'use'.
Am I doing something terribly wrong ? Is there any harm in doing something like this ?
I realize that, for instance, if some other package took a ref to a subroutine in package Foo::Bar, after reloading Foo::Bar would still hold a ref to the _old_ instance of that subroutine. And that's a good thing, AFAIK
sub package2filename {
my $package = shift;
$package =~ s[::][/]g;
$package .= '.pm';
return $package;
}sub unload_package {
my $package = shift;
my ($stash, $dynamic); {
no strict 'refs';
$stash = \%{$package . '::'};
} # Figure out if this module was dynamically loaded
for (my $i = 0 ; $i < @DynaLoader::dl_modules ; $i++) {
if ($DynaLoader::dl_modules[$i] eq $package) {
$dynamic = splice(@DynaLoader::dl_librefs, $i);
splice(@DynaLoader::dl_modules, $i);
}
} # wipe every entry in the stash except the sub-stashes
while (my ($name, $glob) = each %$stash) {
if ($name !~ /::$/) {
delete $stash->{$name};
}
} # Unload the .so
if ($dynamic) {
DynaLoader::dl_unload_file($dynamic);
} # Clear package from %INC
delete $INC{package2filename($package)};
}
-- -------------------------------------------------------------------------------- Philippe M. Chiasson m/gozer\@(apache|cpan|ectoplasm)\.org/ GPG KeyID : 88C3A5A5 http://gozer.ectoplasm.org/ F9BF E0C2 480E 7680 1AE5 3631 CB32 A107 88C3A5A5
signature.asc
Description: OpenPGP digital signature
