Currently in modperl 2 you cannot get Apache::Reload and Class::DBI to cooperate properly. The problem is that Apache::Reload wipes out the CODE slot by doing an undef, which leaves a non-working code reference. Therefore UNIVERSAL::can and *foo{CODE} will both say that there is a method/function there, but Bad Things happen if you try to call it.
This confuses Class::DBI (and probably some other modules) on a reload. The attached patch from Steve Caldwell and me fixes that. (There are other issues as well, but Class::Data::Reloadable takes care of them.) Unfortunately this does not preserve the GLOB slot as the old code did, but since we're skipping stashes, I don't think that that is likely to cause problems. Aslo note that we are explicitly closing filehandles. I don't know why the old code was doing so. Personally I'd be inclined not to - Perl will close a filehandle when the last reference to it goes away, and we're leaving a trap for anyone who aliases STDIN, STDOUT or STDERR to a local filehandle. But I'm trying to not change behaviour without knowing the reason for the old, so I'll leave that for someone else to remove. Cheers, Ben --- /usr/lib/perl5/ModPerl/Util.pm 2005-08-11 22:43:50.000000000 -0700 +++ lib/perl5/ModPerl/Util.pm 2005-09-12 13:34:33.282868768 -0700 @@ -38,46 +38,22 @@ 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) { #Skip sub stashes next if /::$/; 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; - } - if ($$fullname) { - my $tmp; # argh, no such thing as an anonymous scalar - *{$fullname} = \$tmp; - undef $$fullname; - } - if (defined &$fullname) { - no warnings; - local $^W = 0; - if (defined(my $p = prototype $fullname)) { - *{$fullname} = eval "sub ($p) {}"; - } - else { - *{$fullname} = sub {}; - } - undef &$fullname; - } + + # I'm not sure why we're closing the filehandles, but the version + # I replaced did the same if (*{$fullname}{IO}) { if (fileno $fullname) { close $fullname; } } + + *{$fullname} = do {local *{$fullname}}; + } #Wipe from %INC