In 2.0.0, if there are heirarchical packages, and Apache2::Reload is configured to reload the 'parent', it blows away the 'children' package namespaces (and doesn't reload the children.) For example, if @INC has:
Fubar.pm Fubar/Child.pm And Apache2::Reload reloads package Fubar, it blows away Fubar::Child::* and only reloads file Fubar.pm. Only a server restart can recover from this point. The actual unloading work is done by ModPerl::Util::unload_package(), whose behavior is contrary to the docs, which say: "unload_package()" takes care to leave sub-stashes intact while deleting the requested stash. So for example if "CGI" and "CGI::Carp" are loaded, calling "unload_package('CGI')" won't affect "CGI::Carp". I only partly understand how unload_package() works, but it seems to just iterate over symbols in the package and blow them away, without regard for the actual file from which the symbol was instantiated. I tried modifying the code to skip over symbols that correspond to a key in %INC, which seems logical and works correctly in my tests, but may not be a complete or perfect solution for reasons beyond my current testing/thinking. However, in my tests, it works correctly if either the parent package, child package, or both are modified. Comments/suggestions about the correctness of this patch requested. Thanks. *** ./blib/lib/ModPerl/Util.pm 2005-05-22 10:14:19.000000000 -0700 --- /usr/lib/perl5/site_perl/5.8.5/i686-linux/ModPerl/Util.pm 2005-05-29 10:09:02.000000000 -0700 *************** *** 36,55 **** --- 36,58 ---- sub unload_package_pp { my $package = shift; no strict 'refs'; my $tab = \%{ $package . '::' }; # below we assign to a symbol first before undef'ing it, to avoid # nuking aliases. If we undef directly we may undef not only the # alias but the original function as well for (keys %$tab) { + if (my ($subpackage) = /(.*)::/) { + next if exists $INC{"$package/$subpackage.pm"}; + } my $fullname = join '::', $package, $_; # code/hash/array/scalar might be imported make sure the gv # does not point elsewhere before undefing each if (%$fullname) { *{$fullname} = {}; undef %$fullname; } if (@$fullname) { *{$fullname} = []; undef @$fullname;