spacer

Webref WebRef   Sitemap · Experts · Tools · Services · Newsletters · About i.com

home / programming / perl / mysqlperl / chap3 / 3 To page 1To page 2To page 3current pageTo page 5To page 6
[previous][next]
Developer News
Mandrake Linux Founder Back, Virtually
Amazon: We're a Technology Company
Sun Expands MySQL With Closed Source

Improving Performance with mod_perl

Variable Scope Effects

mod_perl runs scripts by wrapping them inside a function (one reason for this is that it can assign each script its own unique namespace). This can cause problems due to variable scope. Here is a simple program that illustrates the effect:

#! /usr/bin/perl -w
print "Content-Type: text/html\n\n";
my $x = 0;
f ();
exit (0);

sub f
{
     print $x++, "\n";
}

If you request this script several times from your browser, the script doesn't print 0 each time as you would expect. Instead, the values increase. This occurs even though the variable $x is explicitly initialized to 0. A clue that something is wrong here will be found in the Apache error log:

Variable "$x" will not stay shared at line 5.

(The line number is off due to the script being executed inside the wrapper function.) The difficulty here is that when the script is run inside a wrapper by mod_perl, your entire script becomes a single function, and any functions in the script become inner subroutines. That means f() is an inner subroutine that references a lexically scoped my() variable belonging to its parent subroutine and that isn't passed to it as an argument. As a result, the inner subroutine sees $x with the correct value the first time the script runs. After that, the variable becomes unshared and the inner subroutine continues to use its own unshared value of $x on subsequent invocations. This issue is discussed in more detail in the mod_perl Guide, along with various solutions to the problem. One way to avoid the difficulty is to change the declaration of $x to be global:

#! /usr/bin/perl -w
print "Content-Type: text/html\n\n";
use vars qw($x);
$x = 0;
f ();
exit (0);

sub f
{
     print $x++, "\n";
}

You can declare a variable using my if you want to, as long as you pass it as an argument to any subroutine that needs it, instead of accessing it directly from the subroutine as a global variable. (That's actually the way I prefer to write scripts, which is why you won't see many instances of use vars in this book.) If you want to modify the variable inside the subroutine, pass it by reference:

#! /usr/bin/perl -w
print "Content-type: text/html\n\n";
my $x = 0;
f (\$x);
exit (0);

sub f
{
my $x_ref = shift;

     print ++${$x_ref}, "\n";
}
home / programming / perl / mysqlperl / chap3 / 3 To page 1To page 2To page 3current pageTo page 5To page 6
[previous][next]

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

webref The latest from WebReference.com Browse >
Working with the DOM Stylesheets Collection · Administering RBAC in PHP 5 CMS Framework · xref: Automatic Cross Referencing Script
Sitemap · Experts · Tools · Services · Email a Colleague · Contact FREE Newsletters 
 The latest from internet.com
Combine BottomCount() with Other MDX Functions to Add Sophistication · Creating a Daemon with Python · The Coming Voice-over-WiMAX Revolution


Created: July 13, 2001
Revised: July 13, 2001


URL: http://webreference.com/programming/perl/mysqlperl/chap3/3/4.html