On 6/11/08 15:39, Casey West wrote:
Hi,

Apache2::Reload relies on ModPerl::Util::unload_package_pp to
disassemble a stash entry before importing the code again. I like how
it does this with two exceptions.

Thanks.

First, prototypes. unload_package_pp() takes care to retain the
prototype when redefining a code stash entry. That's a good thing
because it (typically) avoids a warning. Then it removes the
subroutine from the stash using undef(). That's not so hot because
undef takes the liberty to explicitly undefine the prototype of that
subroutine. In the case of Apache2::Reload, what happens next is we
remake a prototyped subroutine - lets use try() from Error.pm for
illustration - and get warnings about mismatched prototypes. perl
believes the prototype for this subroutine is not defined, Error tries
to define it as (&;$), and perl warns about "none vs. (&;$)" prototype
mismatch.

This can be avoided by explicitly deleting the CODE slot in the stash
entry, like this: "delete ${$fullname}{CODE};" This will remove the
body of the coderef but leave the prototype in tact.

Works great for me, but I'd want to make sure this works/is safe back
to the oldest perl we support. In the worse case, that logic could be
made conditionnal on Perl version.

Seems this also fixes David's problem
http://marc.info/?l=apache-modperl&m=123034201530079

Second, constant redefinitions. In this case the assignment of an
empty subroutine (with proper prototype) throws a warning, only in the
case of constant subroutines. Take something created by "use constant"
as an example, and combine that with Apache2::Reload.
unload_package_pp() makes every attempt to turn off warnings but
can't, for whatever reason, make it work for this one. The reason, I
found through copious trial and error and a pairing session with Adam
Foxson, is to turn off the warning directly in the eval, like this:

   *{$fullname} = eval "no warmings 'redefine'; sub ($p) {}";

Cool, that was one of the warnings I couldn't figure out how to silence
in pure-perl.

I am not sure why the redefinition warning is thrown from this lexical
scope. Nevertheless, a solution is found.

Attached is a patch which accounts for these two problems. Please consider it.

Again, if this can be verified/adjusted for older Perls, +1

For bonus points, include a test case!

--
Philippe M. Chiasson     GPG: F9BFE0C2480E7680 1AE53631CB32A107 88C3A5A5
http://gozer.ectoplasm.org/       m/gozer\@(apache|cpan|ectoplasm)\.org/

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@perl.apache.org
For additional commands, e-mail: dev-h...@perl.apache.org

Reply via email to