Web Developer's Virtual Library: Encyclopedia of Web Design Tutorials, Articles and Discussions


WDVL Newsletter

Active Server Pages
JSP/Java Servlets
Microsoft SQL Server
Daily Backup
Dedicated Servers
Streaming Audio/Video
24-hour Support    

jobs.webdeveloper.com

Hiermenus


e-commerce
Partner With Us















Developer Channel
FlashKit.com
JavaScript.com
JavaScriptSource
Developer Jobs
ScriptSearch
StreamingMediaWorld
Web Developer's Journal
Web Developer's Virtual Library
WebDeveloper.com
Webreference
Web Hosts
XMLfiles.com

internet.com
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers


Compilation Amnesia

May 15, 2000

The curious reader will wonder, besides why people are madly buying cars that are too large to fit into parking spaces, why we wrapped the outer code of name_lib.pl inside a seemingly unnecessary init() subroutine, and then called this subroutine from name.cgi? After all, wasn't the require() enough to pull all the code together?

In fact, it is true that if you did not wrap the code of name_lib.pl inside of a subroutine, it would simply have been executed in sequence when name.cgi was called. It seems we didn't really need &name_main::init(); after all. But wait! If you've tried to test this, now hit reload in the browser and execute the script a second time. Something new: "Document returned no data". Try again -- same message. Now what's going on?

When you have "naked" code at the start of your pulled-in package, also known as a BEGIN block, mod_perl generally only executes this code once per compilation. That usually translates into once per child process -- on first invocation. The solution, as we've already seen, is not to code this way, but to enclose your control code inside a subroutine within its package, and call this subroutine from the mod_perl script, exactly as we did in name.cgi.

Stubborn, Too

Not only will mod_perl conveniently "forget" about BEGIN blocks pulled in via require, it will also tend to ignore changes you make to your library packages or modules. Return to the script we've created, name.cgi with the library name_lib.pl pulled in via a require(). Suppose the script doesn't work, or the script does work but we want to make changes to its output. So, we fire up the trusty editor and hack away at name_lib.pl. Heading back to the browser, hit reload with great anticipation, and what happens?

What happens is whatever happened the previous time you ran the script, because mod_perl doesn't see any of the changes you've slaved over! The stubborn little thing does not check to see if name_lib.pl has changed, and so when name.cgi is invoked again it simply pulls in the compiled name_lib.pl that it's been using all along.

One way to shock mod_perl into its senses is the drastic method, akin to cold-water-in-the-face: kill or restart the Apache server. For instance (modify to match your installation):

/usr/local/apache/bin/apachectl restart

That will force it to re-load any requested files from the disk. This method works fine in testing, but assuming you make many small changes to your script during development, you'll quickly find restarting the server everytime you want to test a change rather tedious. No, not coal mining tedious, or transcontinental railroad spike pounding tedious, but tedious nonetheless. Sometimes it's the little things.

Our hero is named StatINC, which is an Apache Perl module that will effectively check the files you pull in via a require() to see if they've been updated, every time your mod_perl script is invoked. To enable StatINC, you'll need to modify the Apache server configuration file, httpd.conf, found in /path/to/apache/conf/ (modify to match your installation).

Find the portion of your httpd.conf file where mod_perl is configured; using last month's example, that section might look like:

Alias /cgi-perl/ "/usr/local/apache/cgi-perl/"    

<Location /cgi-perl> 

 SetHandler perl-script 

 PerlHandler Apache::Registry 

 Options ExecCGI 

 PerlSendHeader On 

</Location>

Now, we need to add three lines to the above (or whatever configuration is similar to the above in your httpd.conf), marked below in bold and red.


PerlModule Apache::StatINC
Alias /cgi-perl/ "/usr/local/apache/cgi-perl/"    

<Location /cgi-perl> 

 SetHandler perl-script 

 PerlHandler Apache::Registry 

 Options ExecCGI 

 PerlSendHeader On

 PerlInitHandler Apache::StatINC

 PerlSetVar StatINCDebug On 

</Location>

With StatINC enabled with debugging on, as seen above, the Apache errorlog will now contain messages when a change to one of your require'd script files is detected:

Apache::StatINC: process 15420 
 reloading /home/username/cgi-bin/test_lib.pl

Repackage Your Way to Success
The Perl You Need to Know
Conclusion


Up to => Home / Authoring / Languages / Perl / PerlfortheWeb




Jupiter Online Media: internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and Jupiter Online Media

Jupitermedia Corporate Info


Legal Notices, Licensing, & Permissions, Privacy Policy.

Web Hosting | Newsletters | Tech Jobs | Shopping | E-mail Offers