You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Justin Luster <ju...@sawtoothsoftware.com> on 2004/11/05 03:53:43 UTC

Global Variables - What is in Memory?

I have been working with Mod_Perl for a few years now and have been
fairly successful.  I thought that I had a fair understanding of how
things worked until today.  I'm using Mod_Perl version 1.0 and I'm just
using the Apache::Registry to speed up regular Perl scripts.

 

Problem #1:

==============

 

I forgot to initialize a global variable!  Bummer.  In my code I declare
global variables like this:

 

use strict;

 

package mylib;

 

# Globals: Set them below

$mylib::strGlobalStudyName = "";

 

I then initialize them with this:

 

sub InitializeMylibGlobals

{

$mylib::strGlobalStudyName = "";

}

 

I call this initialize function every time the script runs.  Anyway I
forgot and so one of my global variables was not initialized.  I was
shocked when I discovered the value from the global variable from
another user stick around.  I know global variables are bad but
sometimes you have to use them.  What are some good work-a-rounds?  

 

But my big question is, is it safe to use global variables at all?  Am I
guaranteed that if I initialize them at the start of my script that they
won't be set by another process before I use them later in my
script???????????????  

 

Problem #2:

==============

I realize that when a Perl library file is "required" in goes into
memory.  And then the next time that that library is needed it will just
be used from memory and not have to be read in again.  I thought that
only files that were "required" went into memory.  Today I was surprised
when it appeared that my main script was in memory.  The main file that
the web users hit in their URL is called "MyAdmin.pl".  This file looks
like this:

 

 

use strict;

 

admin::main();

 

package admin;

 

sub main

{

 

}

1;

 

This file is not required by any other script.  On my machine I had two
different versions of "MyAdmin.pl".  They were in different locations
so:

 

http://www.mysite.com/one/MyAdmin.pl

 

and 

 

http://www.mysite.com/two/MyAdmin.pl
<http://www.mysite.com/one/MyAdmin.pl> 

 

Well, the script in directory "one" started to run the version in
directory "two".  I would understand this behavior if their was a
"required" library file, but in this case there are two main files.
Does the package "admin" stay in memory even though I did not "require"
it?  I have been lead to believe that it does not stay in memory because
when I update MyAdmin.pl with new code I see the new behavior without
having to reset Apache.

 

I would appreciate any help.

 

Thanks.

 

 

 


Re: [mp2] Apache::DBI and Apache::Status

Posted by Stas Bekman <st...@stason.org>.
Scott Scecina wrote:
> I haven't been able to find an answer to this, so I thought I'd throw it
> out here:
> 
> Apache::DBI used to "plugin" to Apache::Status in order to display the DBI
> connections.  Is this not supported in mp2?

Looks like it wasn't ported to mp2. The following patch should do the trick.

I hope Ask integrates it.

--- /tmp/DBI.pm 2004-11-05 16:09:14.779192529 -0500
+++ /tmp/DBI.pm.new     2004-11-05 16:21:03.967049395 -0500
@@ -193,9 +193,18 @@


  # prepare menu item for Apache::Status
+use mod_perl;
+use constant MP2 => ($mod_perl::VERSION >= 1.99);
+my $apache_status_avail = 0;
+$apache_status_avail = 1
+    if !MP2 and $INC{'Apache.pm'}         # is Apache.pm loaded?
+    and Apache->can('module')             # really?
+    and Apache->module('Apache::Status'); # Apache::Status too?
+$apache_status_avail = 1
+    if MP2 and require Apache::Module
+    and Apache::Module::loaded('Apache::Status');

  Apache::Status->menu_item(
-
      'DBI' => 'DBI connections',
      sub {
          my($r, $q) = @_;
@@ -207,9 +216,7 @@
          return \@s;
     }

-) if ($INC{'Apache.pm'}                      # is Apache.pm loaded?
-      and Apache->can('module')               # really?
-      and Apache->module('Apache::Status'));  # Apache::Status too?
+) if $apache_status_avail;

  1;


-- 
__________________________________________________________________
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

-- 
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


[mp2] Apache::DBI and Apache::Status

Posted by Scott Scecina <sc...@soulcage.net>.
I haven't been able to find an answer to this, so I thought I'd throw it
out here:

Apache::DBI used to "plugin" to Apache::Status in order to display the DBI
connections.  Is this not supported in mp2?

I have this in my httpd.conf:

    PerlModule Apache::Status
    PerlRequire conf/mpstartup.pl

"conf/mpstartup.pl" contains (among other things)

    use Apache::DBI;

Yet, /perl-status still just shows:

Embedded Perl version v5.8.4 for Apache/2.0.52 process 4044,
running since Fri Nov 5 10:48:23 2004

PerlRequire'd Files
Perl Configuration
Compiled Registry Scripts
Environment
ISA Tree
Symbol Table Dump
Loaded Modules
Inheritance Tree

I see this on both Win32 and Linux.

Thanks!

- Scott

Scott Scecina





-- 
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


RE: Global Variables - What is in Memory?

Posted by Justin Luster <ju...@sawtoothsoftware.com>.
This clears things up.

Thanks for your help.

Justin

-----Original Message-----
From: Malcolm J Harwood [mailto:mjhlist-modperl@liminalflux.net] 
Sent: Friday, November 05, 2004 9:22 AM
To: modperl@perl.apache.org
Subject: Re: Global Variables - What is in Memory?

On Friday 5 November 2004 11:50 am, Justin Luster wrote:

> > Apache::Registry should mangle scripts to seperate names so that
they
> > don't conflict. However if you are using the same package name in
each
> > case, the last definition to be loaded will be used. Ie. if both
> > one/MyAdmin.pl and two/MyAdmin.pl define admin:main(), whichever
file
> > loaded last will have it's definition used. (Check your error logs
for
> > "redefinition" warnings).

> I'm still not totally clear on this.

> So if I have two scripts:

> http://www.mysite.com/one/MyAdmin.pl
> and
> http://www.mysite.com/two/MyAdmin.pl

> are you saying that the latest one loaded will be used?  So if 
> http://www.mysite.com/two/MyAdmin.pl was loaded last then
> http://www.mysite.com/one/MyAdmin.pl would actually use the script
> contained in two/MyAdmin.pl?  

No.

> The package part though does make sense.  So the
> last "package" loaded stays in memory?

If you load a file with a package definition in it, then load another
file 
that defines a package with the same name (which is what it looks like
you 
are doing) you get a conflict. If you define a function in both package 
definitions with the same name, then whichever one happens to be loaded
last 
will override the previous definition. Usually this results in a 
"Redefinition of package::functioname " message in your error log.

Normally Apache::Registry only loads packages that are requested using
"use 
package" once (there's a package that will check for changes to package
files 
and reload them if they change, but you have to explicitly use it).

However, you have your package definition in your scripts, which is
where the 
problem occurs. Apache::Registry will load each script when it is first 
encountered or when it changes, and if you are running multiprocess
apache 
then each child will load your scripts in an arbitary order. So some 
processes will have the definition from one/MyAdmin.pl and some from 
two/MyAdmin.pl with no way of predicting which, or which process will
answer 
a given request.


With your scripts, you end up with the following packages being known to

mod_perl:

package Apache::ROOT::webdir::one::MyAdminpl
package Apache::ROOT::webdir::two::MyAdminpl
package mylib
...

one/MyAdmin.pl contains the following package definitions:
package Apache::ROOT::webdir::one::MyAdminpl
package mylib

two/MyAdmin.pl contains the following package definitions:
package Apache::ROOT::webdir::two::MyAdminpl
package mylib

However the two definitions of "mylib" are different. You see the
problem?


-- 
"You heard Mr. Garibaldi. You did the right thing."
"Darling, I did the necessary thing. That is not always the same as
 the right thing."
- Janice and Laura Rosen in Babylon 5:"The Quality of Mercy"

-- 
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


-- 
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


Re: Global Variables - What is in Memory?

Posted by Malcolm J Harwood <mj...@liminalflux.net>.
On Friday 5 November 2004 11:50 am, Justin Luster wrote:

> > Apache::Registry should mangle scripts to seperate names so that they
> > don't conflict. However if you are using the same package name in each
> > case, the last definition to be loaded will be used. Ie. if both
> > one/MyAdmin.pl and two/MyAdmin.pl define admin:main(), whichever file
> > loaded last will have it's definition used. (Check your error logs for
> > "redefinition" warnings).

> I'm still not totally clear on this.

> So if I have two scripts:

> http://www.mysite.com/one/MyAdmin.pl
> and
> http://www.mysite.com/two/MyAdmin.pl

> are you saying that the latest one loaded will be used?  So if 
> http://www.mysite.com/two/MyAdmin.pl was loaded last then
> http://www.mysite.com/one/MyAdmin.pl would actually use the script
> contained in two/MyAdmin.pl?  

No.

> The package part though does make sense.  So the
> last "package" loaded stays in memory?

If you load a file with a package definition in it, then load another file 
that defines a package with the same name (which is what it looks like you 
are doing) you get a conflict. If you define a function in both package 
definitions with the same name, then whichever one happens to be loaded last 
will override the previous definition. Usually this results in a 
"Redefinition of package::functioname " message in your error log.

Normally Apache::Registry only loads packages that are requested using "use 
package" once (there's a package that will check for changes to package files 
and reload them if they change, but you have to explicitly use it).

However, you have your package definition in your scripts, which is where the 
problem occurs. Apache::Registry will load each script when it is first 
encountered or when it changes, and if you are running multiprocess apache 
then each child will load your scripts in an arbitary order. So some 
processes will have the definition from one/MyAdmin.pl and some from 
two/MyAdmin.pl with no way of predicting which, or which process will answer 
a given request.


With your scripts, you end up with the following packages being known to 
mod_perl:

package Apache::ROOT::webdir::one::MyAdminpl
package Apache::ROOT::webdir::two::MyAdminpl
package mylib
...

one/MyAdmin.pl contains the following package definitions:
package Apache::ROOT::webdir::one::MyAdminpl
package mylib

two/MyAdmin.pl contains the following package definitions:
package Apache::ROOT::webdir::two::MyAdminpl
package mylib

However the two definitions of "mylib" are different. You see the problem?


-- 
"You heard Mr. Garibaldi. You did the right thing."
"Darling, I did the necessary thing. That is not always the same as
 the right thing."
- Janice and Laura Rosen in Babylon 5:"The Quality of Mercy"

-- 
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


RE: Global Variables - What is in Memory?

Posted by Justin Luster <ju...@sawtoothsoftware.com>.
Thank you for the great response to my questions.

> Why initialise your data in a seperate function? Is there a reason for
not 
> doing: 

> use strict;
> package mylib;
> $strGlobalStudyName = "value"?

My $mylib::strGlobalStudyName is not a constant.  Every process might
need to change it.  So I need to make sure to initialize it on every
call.

> Apache::Registry should mangle scripts to seperate names so that they
> don't 
> conflict. However if you are using the same package name in each case,
the 
> last definition to be loaded will be used. Ie. if both 
> one/MyAdmin.pl and two/MyAdmin.pl define admin:main(), whichever file
> loaded 
> last will have it's definition used. (Check your error logs for 
> "redefinition" warnings).

I'm still not totally clear on this.  

So if I have two scripts:

http://www.mysite.com/one/MyAdmin.pl
and
http://www.mysite.com/two/MyAdmin.pl

are you saying that the latest one loaded will be used?  So if
http://www.mysite.com/two/MyAdmin.pl was loaded last then
http://www.mysite.com/one/MyAdmin.pl would actually use the script
contained in two/MyAdmin.pl?  Given my experience with Mod_Perl I find
that hard to believe.  The package part though does make sense.  So the
last "package" loaded stays in memory?  

I'm still struggling with this area.

Thanks,

Justin









-----Original Message-----
From: Malcolm J Harwood [mailto:mjhlist-modperl@liminalflux.net] 
Sent: Friday, November 05, 2004 7:09 AM
To: modperl@perl.apache.org
Subject: Re: Global Variables - What is in Memory?

On Thursday 4 November 2004 09:53 pm, Justin Luster wrote:

> Problem #1:

> I forgot to initialize a global variable!  Bummer.  In my code I
declare
> global variables like this:

> use strict;
> package mylib;
> # Globals: Set them below
> $mylib::strGlobalStudyName = "";
> I then initialize them with this:

> sub InitializeMylibGlobals
> {
> $mylib::strGlobalStudyName = "";
> }

Why initialise your data in a seperate function? Is there a reason for
not 
doing: 

use strict;
package mylib;
$strGlobalStudyName = "value"?

and then just referencing it as "$mylib::strGlobalStudyName" when you
need it?

> I call this initialize function every time the script runs.  Anyway I
> forgot and so one of my global variables was not initialized.  I was
> shocked when I discovered the value from the global variable from
> another user stick around.  

What else would you expect? It's a global, therefor unless you change
the 
value it holds the last thing it was set to. You are running
Apache::Registry 
and thus the code is not recompiled every time, so the values of globals
from 
previous requests are retained (on a per process basis).

> What are some good work-a-rounds?

- If you want to go that far, you could write your own handler that
always 
initialises your data. 
- If the values are constants, define them as such.
- Use a globals object, have the new function do your initialisation,
your 
script can't access it without explictly creating the object (so you
know 
your scripts can't forget to call it) and it goes out of scope at the
end of 
your script so the values are discarded.

> But my big question is, is it safe to use global variables at all?  Am
I
> guaranteed that if I initialize them at the start of my script that
they
> won't be set by another process before I use them later in my
> script???????????????

They can't be set in another process, each process has it's own copy. It
can 
be set by another script being run by the same apache process however. 
Scripts are atomic so you can't have a situation where one script
affects 
another that is still running (unless you deliberately set up shared
memory).

> Problem #2:

> I realize that when a Perl library file is "required" in goes into
> memory.  And then the next time that that library is needed it will
just
> be used from memory and not have to be read in again.  I thought that
> only files that were "required" went into memory.  Today I was
surprised
> when it appeared that my main script was in memory.  

This is what mod_perl does. 

> The main file that the web users hit in their URL is called
"MyAdmin.pl". 
> This file looks like this:

> use strict;
> admin::main();

> package admin;
> sub main
> {
> }
> 1;

> This file is not required by any other script.  On my machine I had
two
> different versions of "MyAdmin.pl".  They were in different locations
> so:
> http://www.mysite.com/one/MyAdmin.pl
> and
> http://www.mysite.com/two/MyAdmin.pl
> <http://www.mysite.com/one/MyAdmin.pl>

> Well, the script in directory "one" started to run the version in
> directory "two".  I would understand this behavior if their was a
> "required" library file, but in this case there are two main files.

Apache::Registry should mangle scripts to seperate names so that they
don't 
conflict. However if you are using the same package name in each case,
the 
last definition to be loaded will be used. Ie. if both 
one/MyAdmin.pl and two/MyAdmin.pl define admin:main(), whichever file
loaded 
last will have it's definition used. (Check your error logs for 
"redefinition" warnings).

> Does the package "admin" stay in memory even though I did not
"require"
> it?

It appears to be defined within your script, packages are not
independent of 
the files they are in, so you've defined and used it, the script is not 
discarded (because you're using Apache::Registry) so the package stays
in 
memory.

> I have been lead to believe that it does not stay in memory because 
> when I update MyAdmin.pl with new code I see the new behavior without
> having to reset Apache.

Apache::Registry caches scripts and reloads them when they change. So
when you 
edit one of your scripts it will be reloaded, becoming the "latest
defintion" 
of admin::main() and overwriting the previous version.

see also:
http://perl.apache.org/docs/1.0/guide/intro.html#Apache__Registry

-- 
"The Universe doesn't give you any points for doing things that are
easy."
- Sheridan to Garibaldi in Babylon 5:"The Geometry of Shadows"

-- 
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


-- 
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


Re: Global Variables - What is in Memory?

Posted by Malcolm J Harwood <mj...@liminalflux.net>.
On Thursday 4 November 2004 09:53 pm, Justin Luster wrote:

> Problem #1:

> I forgot to initialize a global variable!  Bummer.  In my code I declare
> global variables like this:

> use strict;
> package mylib;
> # Globals: Set them below
> $mylib::strGlobalStudyName = "";
> I then initialize them with this:

> sub InitializeMylibGlobals
> {
> $mylib::strGlobalStudyName = "";
> }

Why initialise your data in a seperate function? Is there a reason for not 
doing: 

use strict;
package mylib;
$strGlobalStudyName = "value"?

and then just referencing it as "$mylib::strGlobalStudyName" when you need it?

> I call this initialize function every time the script runs.  Anyway I
> forgot and so one of my global variables was not initialized.  I was
> shocked when I discovered the value from the global variable from
> another user stick around.  

What else would you expect? It's a global, therefor unless you change the 
value it holds the last thing it was set to. You are running Apache::Registry 
and thus the code is not recompiled every time, so the values of globals from 
previous requests are retained (on a per process basis).

> What are some good work-a-rounds?

- If you want to go that far, you could write your own handler that always 
initialises your data. 
- If the values are constants, define them as such.
- Use a globals object, have the new function do your initialisation, your 
script can't access it without explictly creating the object (so you know 
your scripts can't forget to call it) and it goes out of scope at the end of 
your script so the values are discarded.

> But my big question is, is it safe to use global variables at all?  Am I
> guaranteed that if I initialize them at the start of my script that they
> won't be set by another process before I use them later in my
> script???????????????

They can't be set in another process, each process has it's own copy. It can 
be set by another script being run by the same apache process however. 
Scripts are atomic so you can't have a situation where one script affects 
another that is still running (unless you deliberately set up shared memory).

> Problem #2:

> I realize that when a Perl library file is "required" in goes into
> memory.  And then the next time that that library is needed it will just
> be used from memory and not have to be read in again.  I thought that
> only files that were "required" went into memory.  Today I was surprised
> when it appeared that my main script was in memory.  

This is what mod_perl does. 

> The main file that the web users hit in their URL is called "MyAdmin.pl". 
> This file looks like this:

> use strict;
> admin::main();

> package admin;
> sub main
> {
> }
> 1;

> This file is not required by any other script.  On my machine I had two
> different versions of "MyAdmin.pl".  They were in different locations
> so:
> http://www.mysite.com/one/MyAdmin.pl
> and
> http://www.mysite.com/two/MyAdmin.pl
> <http://www.mysite.com/one/MyAdmin.pl>

> Well, the script in directory "one" started to run the version in
> directory "two".  I would understand this behavior if their was a
> "required" library file, but in this case there are two main files.

Apache::Registry should mangle scripts to seperate names so that they don't 
conflict. However if you are using the same package name in each case, the 
last definition to be loaded will be used. Ie. if both 
one/MyAdmin.pl and two/MyAdmin.pl define admin:main(), whichever file loaded 
last will have it's definition used. (Check your error logs for 
"redefinition" warnings).

> Does the package "admin" stay in memory even though I did not "require"
> it?

It appears to be defined within your script, packages are not independent of 
the files they are in, so you've defined and used it, the script is not 
discarded (because you're using Apache::Registry) so the package stays in 
memory.

> I have been lead to believe that it does not stay in memory because 
> when I update MyAdmin.pl with new code I see the new behavior without
> having to reset Apache.

Apache::Registry caches scripts and reloads them when they change. So when you 
edit one of your scripts it will be reloaded, becoming the "latest defintion" 
of admin::main() and overwriting the previous version.

see also: http://perl.apache.org/docs/1.0/guide/intro.html#Apache__Registry

-- 
"The Universe doesn't give you any points for doing things that are easy."
- Sheridan to Garibaldi in Babylon 5:"The Geometry of Shadows"

-- 
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


RE: Global Variables - What is in Memory?

Posted by Perrin Harkins <pe...@elem.com>.
On Fri, 2004-11-05 at 12:18, Justin Luster wrote:
> So what you are saying is that 
> 
> http://www.mysite.com/one/MyAdmin.pl
> and
> http://www.mysite.com/two/MyAdmin.pl
> 
> get different package names (because they are in different directories)
> and so stay separate, but because I have declared a package inside of
> them with a common name that package goes into a common package name and
> will be shared by both scripts?

Yes.  Symbols like subs and globals go into the current package. 
(Packages have no relation to file names, except that "use My::Foo" will
try to guess a file name based on what you give it.)  You've declared
the same package in both places, so one is overwriting the other.

The link that Malcolm gave provides a good description of what happens
to your script when you run it under Registry.

- Perrin


-- 
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


RE: Global Variables - What is in Memory?

Posted by Justin Luster <ju...@sawtoothsoftware.com>.
Thanks.

So what you are saying is that 

http://www.mysite.com/one/MyAdmin.pl
and
http://www.mysite.com/two/MyAdmin.pl

get different package names (because they are in different directories)
and so stay separate, but because I have declared a package inside of
them with a common name that package goes into a common package name and
will be shared by both scripts?

Thanks Perrin.

-----Original Message-----
From: Perrin Harkins [mailto:perrin@elem.com] 
Sent: Friday, November 05, 2004 9:03 AM
To: Justin Luster
Cc: modperl@perl.apache.org
Subject: Re: Global Variables - What is in Memory?

Hi Justin,

> use strict;
> package mylib;
> # Globals: Set them below
> 
> $mylib::strGlobalStudyName = "";

You could also just say "our $strGlobalStudyName;" here.

> I call this initialize function every time the script runs.  Anyway I
> forgot and so one of my global variables was not initialized.  I was
> shocked when I discovered the value from the global variable from
> another user stick around.

That's what they do.  Globals don't go out of scope, so they retain
their values.

> I know global variables are bad but sometimes you have to use them. 
> What are some good work-a-rounds?  

Using lexicals, or sometimes singleton objects with accessors.  It kind
of depends on why you thought you needed to use a global in the first
place.

> But my big question is, is it safe to use global variables at all?  Am
> I guaranteed that if I initialize them at the start of my script that
> they won't be set by another process before I use them later in my
> script???????????????

You are guaranteed of that, because each mod_perl request is handled by
a separate process in mod_perl 1.  (Even if you use a threaded MPM in
MP2 you are still safe unless you explicitly declare the variable shared
between threads.)

> Today I was surprised when it appeared that my main script was in
> memory.

Yes, that's what Apache::Registry does.  This is described in the
Apache::Registry documentation and other places in the mod_perl docs
online.

> Well, the script in directory "one" started to run the version in
> directory "two".  I would understand this behavior if their was a
> "required" library file, but in this case there are two main files. 
> Does the package "admin" stay in memory even though I did not
> "require" it?

Yes.  Apache::Registry turns it into a module and requires it.  That's
why Registry is fast.  If you didn't declare a package name in that
file, each one would get a different auto-generated package name and
they would not overlap.  The automatic package name is based on the
URL.  Look at the Registry code if you want to see how this works.  It's
short and pure perl.

> I have been lead to believe that it does not stay in memory because
> when I update MyAdmin.pl with new code I see the new behavior without
> having to reset Apache.

It just checks to see if the file has been updated and reloads it if it
has.

- Perrin


-- 
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


-- 
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


Re: Global Variables - What is in Memory?

Posted by Perrin Harkins <pe...@elem.com>.
Hi Justin,

> use strict;
> package mylib;
> # Globals: Set them below
> 
> $mylib::strGlobalStudyName = "";

You could also just say "our $strGlobalStudyName;" here.

> I call this initialize function every time the script runs.  Anyway I
> forgot and so one of my global variables was not initialized.  I was
> shocked when I discovered the value from the global variable from
> another user stick around.

That's what they do.  Globals don't go out of scope, so they retain
their values.

> I know global variables are bad but sometimes you have to use them. 
> What are some good work-a-rounds?  

Using lexicals, or sometimes singleton objects with accessors.  It kind
of depends on why you thought you needed to use a global in the first
place.

> But my big question is, is it safe to use global variables at all?  Am
> I guaranteed that if I initialize them at the start of my script that
> they won’t be set by another process before I use them later in my
> script???????????????

You are guaranteed of that, because each mod_perl request is handled by
a separate process in mod_perl 1.  (Even if you use a threaded MPM in
MP2 you are still safe unless you explicitly declare the variable shared
between threads.)

> Today I was surprised when it appeared that my main script was in
> memory.

Yes, that's what Apache::Registry does.  This is described in the
Apache::Registry documentation and other places in the mod_perl docs
online.

> Well, the script in directory “one” started to run the version in
> directory “two”.  I would understand this behavior if their was a
> “required” library file, but in this case there are two main files. 
> Does the package “admin” stay in memory even though I did not
> “require” it?

Yes.  Apache::Registry turns it into a module and requires it.  That's
why Registry is fast.  If you didn't declare a package name in that
file, each one would get a different auto-generated package name and
they would not overlap.  The automatic package name is based on the
URL.  Look at the Registry code if you want to see how this works.  It's
short and pure perl.

> I have been lead to believe that it does not stay in memory because
> when I update MyAdmin.pl with new code I see the new behavior without
> having to reset Apache.

It just checks to see if the file has been updated and reloads it if it
has.

- Perrin


-- 
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