Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: ModPerl: Dev

[PATCH] prototypes/constant redefinition warnings from ModPerl::Util

 

 

ModPerl dev RSS feed   Index | Next | Previous | View Threaded


casey at geeknest

Nov 6, 2008, 12:39 PM

Post #1 of 6 (2805 views)
Permalink
[PATCH] prototypes/constant redefinition warnings from ModPerl::Util

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.

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.

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) {}";

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.

Cheers,

--
Casey West
Attachments: mp-ap2-reload-warnings-stfu.patch (0.66 KB)


geoff at modperlcookbook

Nov 8, 2008, 6:14 AM

Post #2 of 6 (2661 views)
Permalink
Re: [PATCH] prototypes/constant redefinition warnings from ModPerl::Util [In reply to]

- undef &$fullname;
+ delete ${$fullname}{CODE};

I swear there is some p5p history here that treats that slot differently
when it's undef versus exists. IIRC an early 5.8.0 iteration broke
mod_perl because of exactly this (or, if you prefer, mod_perl exposed a
feature of perl that we prefer to remain ;)

anyway, I'm a little backed up, but I don't post to p5p often, so you
should be able to find the thread - I'm pretty sure I brought it up, but
I can't recall.

anyway, I think we need to check that before committing this part.

--Geoff

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe [at] perl
For additional commands, e-mail: dev-help [at] perl


geoff at modperlcookbook

Nov 8, 2008, 5:55 PM

Post #3 of 6 (2655 views)
Permalink
Re: [PATCH] prototypes/constant redefinition warnings from ModPerl::Util [In reply to]

Geoffrey Young wrote:
>
> - undef &$fullname;
> + delete ${$fullname}{CODE};
>
> I swear there is some p5p history here that treats that slot differently
> when it's undef versus exists. IIRC an early 5.8.0 iteration broke
> mod_perl because of exactly this (or, if you prefer, mod_perl exposed a
> feature of perl that we prefer to remain ;)
>
> anyway, I'm a little backed up, but I don't post to p5p often, so you
> should be able to find the thread - I'm pretty sure I brought it up, but
> I can't recall.
>
> anyway, I think we need to check that before committing this part.

http://marc.info/?l=perl5-porters&m=106752791011060&w=2

--Geoff

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe [at] perl
For additional commands, e-mail: dev-help [at] perl


casey at geeknest

Nov 10, 2008, 7:30 AM

Post #4 of 6 (2641 views)
Permalink
Re: [PATCH] prototypes/constant redefinition warnings from ModPerl::Util [In reply to]

On Sat, Nov 8, 2008 at 8:55 PM, Geoffrey Young
<geoff [at] modperlcookbook> wrote:
> Geoffrey Young wrote:
>>
>> - undef &$fullname;
>> + delete ${$fullname}{CODE};
>>
>> I swear there is some p5p history here that treats that slot differently
>> when it's undef versus exists. IIRC an early 5.8.0 iteration broke
>> mod_perl because of exactly this (or, if you prefer, mod_perl exposed a
>> feature of perl that we prefer to remain ;)
[...]
> http://marc.info/?l=perl5-porters&m=106752791011060&w=2

Geoff,

Are you sure the referenced issue is the same one that line is trying
to handle? It appears that the undef vs delete issue is related to
loading Perl modules from disk and managing the %INC cache. The delete
in my patch is about tearing down the stash before the package's
reference is eliminated from %INC. I'm worried we're talking about two
different things. Do you see what I mean?

Cheers,

--
Casey West

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe [at] perl
For additional commands, e-mail: dev-help [at] perl


geoff at modperlcookbook

Nov 12, 2008, 6:40 AM

Post #5 of 6 (2635 views)
Permalink
Re: [PATCH] prototypes/constant redefinition warnings from ModPerl::Util [In reply to]

Casey West wrote:
> On Sat, Nov 8, 2008 at 8:55 PM, Geoffrey Young
> <geoff [at] modperlcookbook> wrote:
>> Geoffrey Young wrote:
>>> - undef &$fullname;
>>> + delete ${$fullname}{CODE};
>>>
>>> I swear there is some p5p history here that treats that slot differently
>>> when it's undef versus exists. IIRC an early 5.8.0 iteration broke
>>> mod_perl because of exactly this (or, if you prefer, mod_perl exposed a
>>> feature of perl that we prefer to remain ;)
> [...]
>> http://marc.info/?l=perl5-porters&m=106752791011060&w=2
>
> Geoff,
>
> Are you sure the referenced issue is the same one that line is trying
> to handle? It appears that the undef vs delete issue is related to
> loading Perl modules from disk and managing the %INC cache. The delete
> in my patch is about tearing down the stash before the package's
> reference is eliminated from %INC. I'm worried we're talking about two
> different things. Do you see what I mean?

we probably are talking about two different things. in truth, it just
looked familiar - I wasn't entirely sure about the context, which is why
I went hunting for the thread :)

--Geoff

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe [at] perl
For additional commands, e-mail: dev-help [at] perl


gozer at ectoplasm

Jan 7, 2009, 9:43 PM

Post #6 of 6 (2155 views)
Permalink
Re: [PATCH] prototypes/constant redefinition warnings from ModPerl::Util [In reply to]

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-unsubscribe [at] perl
For additional commands, e-mail: dev-help [at] perl

ModPerl dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.