Also forgot to mention, this is running:

mod_perl 1.29
perl 5.8.4
apache 1.3.27

and ..

SunOS *** 5.9 Generic_112234-08 i86pc i386 i86pc

Cheers


On Mon, 2004-10-04 at 16:15, David Radunz wrote:
> Hi All,
> 
>   I have looked high and low to work out how to avoid the 'Constant
> subroutine redefined' warnings in the error log, followed by the
> 'Prototype missmatch:' error upon subsequent hits to the apache child
> process - but, I have not been able to find an easy solution. The
> warnings are caused by the 'flush_namespace' routine of Apache::PerlRun
> which attempts to reset/nullify everything - including constants. When a
> constant is redefined it causes a warning in the error_log, and when the
> constant gets reset upon the next run of the script the prototype doesnt
> match as its reset incorrectly.
> 
>   I found a message from Stass Beckman saying that you could use a
> $SIG{__WARN__} handler to filter the warnings. This works for the
> 'Constant subroutine redefined' warnings, but not the 'Prototype
> missmatch:' warnings (even thou I modified it to take both into
> account), no matter where i add the $SIG{__WARN__} handler it never gets
> called in the case of 'Prototype missmatch:' - not even when its defined
> in the startup.pl
> 
>   So I decided to work out a way to modify Apache::PerlRun so that it
> did not redefine constants. There is no need to nullify constants as
> they will not and CAN NOT change between child instances, and
> documentation indicates that the 'Constant subroutine redefined' warning
> means that the original value will be retained anyway (i.e. you cant
> change a constants value).
> 
>   Constants in perl are anonymous code references with a blank
> prototype, that is how they are created within constant.pm here is a
> snippet:
> 
> *{$fullname} = sub () { };
> 
> So if you had:
> 
> use constant TRUE => 1;
> 
> it would become:
> 
> *{$fullname} = sub () { 1 };
> 
> where $fullname was main::TRUE
> 
>   When a subroutine is defined with a prototype of '()' and it returns a
> constant result when compiled, it becomes a 'constant subroutine'.
> Hence, constants are meerly constant subroutines.
> 
>   So now for the changes I made to PerlRun.pm, below is the original
> code:
> 
> 
>         if (defined &$fullname) {
>             no warnings;
>             local $^W = 0;
>             if (defined(my $p = prototype $fullname)) {
>                 *{$fullname} = eval "sub ($p) {}";
>             }
>             else {
>                 *{$fullname} = sub {};
>             }
>           undef &$fullname;
>       }
> 
> So, this code would reset every subroutine to a blank anonymous
> subroutine, using the correct (current) prototype. And then undefine it.
> 
> My patch:
> 
>         if (defined &$fullname) {
>             no warnings;
>             local $^W = 0;
>             if (defined(my $p = prototype $fullname)) {
>                 # We DONT want to redefine constant subroutines (sub ())
>                 if ($p) {
>                      *{$fullname} = eval "sub ($p) {}";
>                      undef &$fullname;
>                 }
>             }
>             else {
>                 *{$fullname} = sub {};
>                 undef &$fullname;
>             }
>         }
> 
> This code will reset every subroutine that does not have an empty
> prototype and then undef it. So basically the 'sub () {}' defined
> subroutines are not reset (but sub {} and sub ($) {} are reset).
> 
> Now, im aware this is not an ideal solution due to the fact that any
> subroutines declared in a script with a () prototype will not be reset.
> But on the flip side of the coin all constants will be left intact and
> any warnings in the error log avoided. My question is, what caveats
> would there be in not resetting a subroutine? I have ran some tests to
> see how subroutines setup in this way would work and the tests appear to
> be good.
> 
> For example:
> 
> print STDERR 'time_constant = '. &time_constant(). "\n";
> sub time_constant () {
>    time. ' '. $$;
> }
> 
> running under 'httpd -X'
> 
> would produce a different time each request, and the same process id.
> 
> as did..
> 
> my $time_constant = sub () { time. ' '. $$ };
> print STDERR 'var time_constant = '. &{$time_constant}. "\n";
> 
> 
> Sorry this email is a tad long, but its quite complicated to explain.
> 
> Cheers,
> 
> 
> -- 
> David Radunz,
> Developer / Programmer
> 
> Netspace Online Systems Pty Ltd
> Ground Floor, 293 Camberwell Road
> Camberwell, Victoria 3124
> Ph:  +613 9811 0087
> Fx:  +613 9811 0044
> Mo:  +614 0549 9719
> Em:  [EMAIL PROTECTED]
> 
> This email and any files transmitted with it are confidential and intended solely 
> for the 
> use of the individual or entity to whom they are addressed. Please notify the sender 
> immediately by email if you have received this email by mistake and delete this 
> email 
> from your system. Please note that any views or opinions presented in this email are 
> solely
>  those of the author and do not necessarily represent those of the organisation. 
> Finally, the recipient should check this email and any attachments for the presence 
> of 
> viruses. The organisation accepts no liability for any damage caused by any virus 
> transmitted by this email. 
-- 
David Radunz,
Developer / Programmer

Netspace Online Systems Pty Ltd
Ground Floor, 293 Camberwell Road
Camberwell, Victoria 3124
Ph:  +613 9811 0087
Fx:  +613 9811 0044
Mo:  +614 0549 9719
Em:  [EMAIL PROTECTED]

-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html

Reply via email to