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