In private mail Stas Bekman <[EMAIL PROTECTED]> writes: > oops, that should be the modperl list... at modperl-docs we discuss > mostly site/docs techical issues and there are very few people on this > list to get enough exposure for this kind of feedback request.
Patch for "The First Mystery" section of the mod_perl porting guide as per my conversation with Stas at YAPC::Europe::2003. Takes out the suggestion of creating a Perl4-style library in the same directory as a means to port CGI scripts. Replaces it with something simpler and more reliable. I've also changed "If you put your code into a library or module..." to "If you put all your code into modules..." because if you put your code into a Perl4-style library and then require it in more than one registry script terrible things happen. I don't think this is the place to explain this so I think the guide should just say "modules" and leave it at that. Probably the library problem should be explained elsewhere in the guide. Once this one is sorted out, a patch for perl_reference.pod will follow. --- porting.pod.orig Thu Aug 14 18:02:27 2003 +++ porting.pod Fri Aug 15 13:37:33 2003 @@ -228,44 +228,42 @@ It's important to understand that the I<inner subroutine> effect happens only with code that C<Apache::Registry> wraps with a -declaration of the C<handler> subroutine. If you put your code into a -library or module, which the main script require()'s or use()'s, this -effect doesn't occur. +declaration of the C<handler> subroutine. If you put all your code +into modules, which the main script use()s, this effect doesn't occur. -For example if we move the code from the script into the subroutine -I<run>, place the subroutines into the I<mylib.pl> file, save it in -the same directory as the script itself and require() it, there will -be no problem at all. (Don't forget the C<1;> at the end of the -library or the require() might fail.) +Do not use simple Perl4-style libraries located in the same directory +as the script. This technique was recommended by a previous version +of this guide but is seriously flawed. Subroutines in such libraries +will only be available to the first script in any given interpreter +thread to require() a library of any given name. This can lead to +strange sporadic failures. It also won't work at all under mod_perl2 +because the current working directory is not the directory containing +the script. + +The easiest and the fastest way to solve the nested subroutines +problem is to change C<my> to C<local> C<our> for all variables for +which you get the warning. The C<handler> subroutines are never +called re-entrantly and each resides in a package to itself. Most of +the usual disadvantates of package scoped variables are, therefore, +not a concern. - mylib.pl: - --------- - my $counter; - sub run{ - print "Content-type: text/plain\r\n\r\n"; - $counter = 0; - for (1..5) { - increment_counter(); - } + counter.pl: + ---------- + #!/usr/bin/perl -w + use strict; + + print "Content-type: text/plain\r\n\r\n"; + + local our $counter = 0; + + for (1..5) { + increment_counter(); } + sub increment_counter{ $counter++; print "Counter is equal to $counter !\r\n"; } - 1; - - counter.pl: - ---------- - use strict; - require "./mylib.pl"; - run(); - -This solution provides the easiest and the fastest way to solve the -nested subroutines problem, since all you have to do is to move the -code into a separate file, by first wrapping the initial code into -some function that you later will call from the script and keeping the -lexically scoped variables that could cause the problem out of this -function. But as a general rule of thumb, unless the script is very short, I tend to write all the code in external libraries, and to have only a -- Reporting bugs: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html