You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Bill Catlan <wc...@optonline.net> on 2002/05/04 00:22:31 UTC

Scope of Perl Special Variables

Hello,

The online mod_perl guide
(http://thingy.kcilink.com/modperlguide/perl/The_Scope_of_the_Special_Perl_Va.ht
ml) states:

"Special Perl variables like $| (buffering), $^T (script's start time), $^W
(warnings mode), $/ (input record separator), $\ (output record separator) and
many more are all true global variables; they do not belong to any particular
package (not even main::) and are universally available. This means that if you
change them, you change them anywhere across the entire program; furthermore you
cannot scope them with my()."

My question pertains the CGI %ENV hash.  First, I'm assumong that this is a
global variable in the sense of a Perl Special Variable, and not just a main::
or other package global.  My question is how is it the case that the %ENV
variable script instance might be working with doesn't get clobbered or "reset"
by the next incoming request.  Are some variables, like %ENV treated differently
by mod_perl?

Also, how can special variables be reliably initialized?  For example, if one
request provides a certain attribute, such as HTTP_IDENT, but a subsequent
request does not, how do I know that the value of $ENV{HTTP_IDENT} on the second
request will indeed be undefined?

Thanks.

Bill



Re: Scope of Perl Special Variables

Posted by Stas Bekman <st...@stason.org>.
Bill Catlan wrote:
> Stas Bekman wrote:
> 
> 
>>This explains why by default %ENV is set for each request afresh.
>>http://perl.apache.org/guide/performance.html#PerlSetupEnv_Off
> 
> 
> Great.  Thank you Stas.  Now I know /how/ that happens, but I don't know /why/
> the existing inctances' ENV is not clobbered.
> 
> My guess is that a localized copy of the %ENV variable is created by the above
> referenced process, thus no clobbering of existing instances' %ENV occurs.
> Would that be correct?

Can you send a reproducable example of a problem? For example this code 
does the right thing:

$r->send_http_header('text/plain');
print exists $ENV{FOO} ? "$ENV{FOO}\n" : "NONE\n";
local $ENV{FOO} = "BAR";
print exists $ENV{FOO} ? "$ENV{FOO}\n" : "NONE\n";

it'll always print:
NONE
BAR

Make sure that you test under httpd -X mode so you won't get mislead.

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


Re: Scope of Perl Special Variables

Posted by Bill Catlan <wc...@optonline.net>.
Stas Bekman wrote:

> This explains why by default %ENV is set for each request afresh.
> http://perl.apache.org/guide/performance.html#PerlSetupEnv_Off

Great.  Thank you Stas.  Now I know /how/ that happens, but I don't know /why/
the existing inctances' ENV is not clobbered.

My guess is that a localized copy of the %ENV variable is created by the above
referenced process, thus no clobbering of existing instances' %ENV occurs.
Would that be correct?

-Bill


Re: Scope of Perl Special Variables

Posted by Stas Bekman <st...@stason.org>.
Bill Catlan wrote:
> Hello,
> 
> The online mod_perl guide
> (http://thingy.kcilink.com/modperlguide/perl/The_Scope_of_the_Special_Perl_Va.ht
> ml) states:
> 
> "Special Perl variables like $| (buffering), $^T (script's start time), $^W
> (warnings mode), $/ (input record separator), $\ (output record separator) and
> many more are all true global variables; they do not belong to any particular
> package (not even main::) and are universally available. This means that if you
> change them, you change them anywhere across the entire program; furthermore you
> cannot scope them with my()."
> 
> My question pertains the CGI %ENV hash.  First, I'm assumong that this is a
> global variable in the sense of a Perl Special Variable, and not just a main::
> or other package global.  My question is how is it the case that the %ENV
> variable script instance might be working with doesn't get clobbered or "reset"
> by the next incoming request.  Are some variables, like %ENV treated differently
> by mod_perl?
> 
> Also, how can special variables be reliably initialized?  For example, if one
> request provides a certain attribute, such as HTTP_IDENT, but a subsequent
> request does not, how do I know that the value of $ENV{HTTP_IDENT} on the second
> request will indeed be undefined?

This explains why by default %ENV is set for each request afresh.
http://perl.apache.org/guide/performance.html#PerlSetupEnv_Off

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


Re: Scope of Perl Special Variables

Posted by Bill Catlan <wc...@optonline.net>.
> I thought that using 'local' would successfully scope those globals to
> within a sub, so you could,k for example, slurp an entire file by doing:
>
> local $/ = undef;
> my $file = <FH>;
>
> Or am I wrong in that?  I use it frequently, and don't seem to have any
> troubles.
>
> --Jon R.

It is my understanding that that is correct.  I am a novice at mod_perl, but
your experience would seem to match up with my understanding of the Guide.

Local would scope it to within the enclosing block; so you could scope a
variable within a bare block so that it would be local to you package, but
shareable between subs.

# $/ equals default, global value
{
    local $/ = undef;

    sub { ... # $/ equals undef }
    sub { ... # $/ equals undef }
    sub { local $/ = "\n\n"; # localized value for sub }

    # $/ back to undef
}
# $/ back to default, global value

-Bill


Re: Scope of Perl Special Variables

Posted by Mark Fowler <ma...@twoshortplanks.com>.
On Sun, 5 May 2002, Jon wrote:

> I thought that using 'local' would successfully scope those globals to
> within a sub, so you could,k for example, slurp an entire file by doing:
> 
> local $/ = undef;
> my $file = <FH>;
> 
> Or am I wrong in that?  I use it frequently, and don't seem to have any
> troubles.

Okay, local takes a temporary copy of the variable and then restores the
original value at the end of the block.  It's the same variable though. my
creates a new variable that is only visible from within the block and
can't be seen from other subroutines.  With my there are two variables 
that just happen to be called the same things, and which one you get 
depends if you're in within the enclosing block.

The difference is that when you use local any subroutines that you call
from within that subroutine will *also* see the variable.  With a 
my variable whatever you change can't be seen in other subroutines

The practical difference is if you set $/ and you call any routine from
within that same subroutine (that same block) they will also see the new 
version of $/.  This means that anything that you call from within that 
routine will also slurp in the whole file when it tries to read a line - 
if it was expecting it or not.

In terms of mod_perl this isn't so bad.  The local is fine when used in a 
subroutine like you described, as this subroutine will be exited by the 
time the handler returns, meaning you won't get any interaction between 
calls.

Of course there's still ways for you to screw yourself over with local, 
but used carefully it should be fine...

Later.

Mark.

-- 
s''  Mark Fowler                                     London.pm   Bath.pm
     http://www.twoshortplanks.com/              mark@twoshortplanks.com
';use Term'Cap;$t=Tgetent Term'Cap{};print$t->Tputs(cl);for$w(split/  +/
){for(0..30){$|=print$t->Tgoto(cm,$_,$y)." $w";select$k,$k,$k,.03}$y+=2}


Re: Scope of Perl Special Variables

Posted by Jon <jo...@mhost.com>.
I thought that using 'local' would successfully scope those globals to
within a sub, so you could,k for example, slurp an entire file by doing:

local $/ = undef;
my $file = <FH>;

Or am I wrong in that?  I use it frequently, and don't seem to have any
troubles.

--Jon R.

PGP Key fingerprint = 12 DA FC 06 AB 4C D6 A4  DE 03 E0 77 D6 DE E0 73
PGP public key available by fingering jon@mhost.com

On Fri, 3 May 2002, Bill Catlan wrote:

> Hello,
> 
> The online mod_perl guide
> (http://thingy.kcilink.com/modperlguide/perl/The_Scope_of_the_Special_Perl_Va.ht
> ml) states:
> 
> "Special Perl variables like $| (buffering), $^T (script's start time), $^W
> (warnings mode), $/ (input record separator), $\ (output record separator) and
> many more are all true global variables; they do not belong to any particular
> package (not even main::) and are universally available. This means that if you
> change them, you change them anywhere across the entire program; furthermore you
> cannot scope them with my()."
> 
> My question pertains the CGI %ENV hash.  First, I'm assumong that this is a
> global variable in the sense of a Perl Special Variable, and not just a main::
> or other package global.  My question is how is it the case that the %ENV
> variable script instance might be working with doesn't get clobbered or "reset"
> by the next incoming request.  Are some variables, like %ENV treated differently
> by mod_perl?
> 
> Also, how can special variables be reliably initialized?  For example, if one
> request provides a certain attribute, such as HTTP_IDENT, but a subsequent
> request does not, how do I know that the value of $ENV{HTTP_IDENT} on the second
> request will indeed be undefined?
> 
> Thanks.
> 
> Bill
> 
>