Brian McCauley wrote:
[...]
Nice, but:

> +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
...
[...]
> +  local our $counter = 0;

local our? That should be either local or our, but not both.


No.


Do I miss something?


Yes.  (I tried to explain this in Paris but I was in danger of causing
you to miss lunch completely).

local() and our() do two quite separate and complementary things.

our() (in effect) declares a lexically scoped alias for a package
variable.

local() restores the old value of a package variable (usually undef)
at the end of the current lexical scope.

In effect you use local() to undef the variable, instead of explicitly initializing it. Why not doing this explictly?


so instead of replacing:

my $counter;

with:

local our $counter;

it's probably better to say:

our $counter = 0;

or if you insist on using both:

our $counter;
local $counter; # undef $counter

later on I show why this is better for user's understanding.

The two combined therefore give a package variable two of the most
useful properties of a lexical one. Of course a real lexical variable
doesn't really become undefined when it does out of scope - it really
becomes anonymous, and iff there are no remaining (unweakened)
references it then gets GCed. But for file-scoped lexicals in the
main script file the difference is usually not that important. Both
effectively get killed at the point where global destruction would
have taken place.


The rest looks good, but that's not the simplest solution as you have
to modify the variables.


Is there a simpler one?  For a typical script with say half a dozen
variables the "would not remain shared" the "local our" solution
requires a dozen keystokes on each of half a dozen lines.

Don't forget that our() is not available before perl 5.6. So we can't quite eliminate the previous solution unless you suggest to go with a back-compatible version:


use vars qw($counter);
local $counter;

and of course the proper solution is:

use vars qw($counter);
$counter = 0; # or undef

which is documented in the perl reference section.

Granted, the original "simplest" solution has its troubles.


The original "simplest" solution involved finding (and subsequently
maintaining) a globally unique filename then splitting the program in
to two parts.  Thereafer you have to maintain two files even on CGI
servers.  I would contend that this "simple solution" is not simple.
If you are going to all that troble you may as well to the extra
804.65m and produce a proper mod_perl handler and a small wrapper to
make it work also in a CGI environment.  Also, as of mod_perl2, the
"simple solution" is not even, as it stands, a solution as it relied
on the script being in the CWD.

Remember, we are talking about mp1 guide patching. Not everything that applies to mp1 applies to mp2. e.g., mp2 requires 5.6+, so we indeed can rely on using our() there. And I hope that the problem with CWD will be resolved once Arthur will fix that.


If you think that using globals + their initialization is a better solution, which will work well in mp1 and mp2, we can replace the lib.pl solution with it, but should add it to the perl reference section.

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com



--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html



Reply via email to