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