On Tue, Apr 27, 2010 at 7:16 AM, André Warnier <a...@ice-sa.com> wrote:
> Now if I configure the first of these subs as a PerlAccessHandler and
> the second as a PerlResponseHandler, what happens to $lexical_mine ?

This is actually import to point out: it makes no difference if you
configure these subs as mod_perl anything.  There is no difference at
all in scoping rules for mod_perl because mod_perl is just the perl
interpreter running inside apache.  The thing that can make it appear
different is the lifecycle of the interpreter, i.e. the fact that it
doesn't exit as soon as your code has run once.  This doesn't change
anything about scoping rules in perl though.

> But for all intents and purposes, this variable is "functionally
> global", in the sense that throughout the life of the Apache child that
> contains this perl interpreter, this variable is "shared", not only by
> the separate handler subs, but even by subsequent invocations of these
> subs in the course of processing all HTTP requests which happen to be
> processed by this Apache child.(*)

I think it's better to say the variable is "persistent" rather than
global, and the reason for that is that you're creating a closure.
Again, not a mod_perl thing.  Any time you reference a lexical
variable from outside the sub you're in, it causes a closure.

> On the other hand, if I configure "finalise" as a PerlSomethingHandler,
> then the $lexical_mine that is defined inside it, does not play along
> with the other one.  It is its own thing, and it will print its own
> incremental sequence 1,1,2,3,4,5
> But it is still "global" in a sense : while "private" to the sub
> "finalise", it nevertheless is shared between consecutive invocations of
> the same finalise() sub by the same Apache child.

No, this isn't true.  It's not a closure, so it will be undefined
every time you enter the sub.  It will also give you a warning about
reusing the name of a lexical from a larger scope.

> So, back to the basics, my interpretation : by default, consider any
> variable as "global/shared" and you'll generally stay out of trouble.

Here's another rule you could use: don't reference lexical variables
defined outside of a sub from within that sub.  Either use globals for
things you want shared, or pass in the data you need as parameters.
Then you won't be surprised by closures messing up your ideas about
scoping.

I also suggest that anyone who finds this confusing should have a look
through the information on variable scoping in the perl man pages,
Programming Perl, or perlmonks.org.  It really pays to understand this
stuff.

- Perrin

Reply via email to