Let's look at a real-world startup file. The elements of the file are shown here, followed by their descriptions.

use strict;

This pragma is worth using in every script longer than half a dozen lines. It will save a lot of time and debugging later.

use lib qw(/home/httpd/lib /home/httpd/extra-lib);

This permanently adds extra directories to @INC, something that's possible only during server startup. At the end of each request's processing, mod_perl resets @INC to the value it had after the server startup. Alternatively, you can use the PERL5LIB environment variable to add extra directories to @INC.

$ENV{MOD_PERL} or die "not running under mod_perl!";

This is a sanity check. If mod_perl wasn't properly built, the server startup is aborted.

use Apache::Registry ( );
use LWP::UserAgent ( );
use Apache::DBI ( );
use DBI ( );

Preload the modules that get used by Perl code serving requests. Unless you need the symbols (variables and subroutines) exported by preloaded modules to accomplish something within the startup file, don't import them—it's just a waste of startup time and memory. Instead, use the empty import list ( ) to tell the import( ) function not to import anything.

use Carp ( );
$SIG{__WARN__} = \&Carp::cluck;

This is a useful snippet to enable extended warnings logged in the error_log file. In addition to basic warnings, a trace of calls is added. This makes tracking potential problems a much easier task, since you know who called what.

The only drawback of this method is that it globally overrides the default warning handler behavior—thus, in some places it might be desirable to change the settings locally (for example, with local $^W=0, or no warnings under Perl 5.6.0 and higher). Usually warnings are turned off on production machines to prevent unnecessary clogging of the error_log file if your code is not very clean. Hence, this method is mostly useful in a development environment.

use CGI ( );
CGI->compile(':all');

Some modules, such as CGI.pm, create their subroutines at runtime via AUTOLOAD to improve their loading time. This helps when the module includes many subroutines but only a few are actually used. (Also refer to the AutoSplit manpage.) Since the module is loaded only once with mod_perl, it might be a good idea to precompile all or some of its methods at server startup. This avoids the overhead of compilation at runtime. It also helps share more compiled code between child processes.

CGI.pm's compile( ) method performs this task. Note that compile( ) is specific to CGI.pm; other modules that implement this feature may use another name for the compilation method.

As with all modules we preload in the startup file, we don't import symbols from them because they will be lost when they go out of the file's scope.

The following code snippet makes sure that when the child process is spawned, a connection to the database is opened automatically, avoiding this performance hit on the first request:

Apache::DBI->connect_on_init
  ("DBI:mysql:database=test;host=localhost",
   "user", "password", {
                        PrintError => 1, # warn( ) on errors
                        RaiseError => 0, # don't die on error
                        AutoCommit => 1, # commit executes immediately
                       }
  );

We discuss this method in detail in Chapter 20.

The file ends with 1;so it can be successfully loaded by Perl.

The entire startup.pl file is shown in Example 4-3.

Example 4-3. startup.pl

use strict;

use lib qw(/home/httpd/lib /home/httpd/extra-lib);
$ENV{MOD_PERL} or die "not running under mod_perl!";

use Apache::Registry ( );
use LWP::UserAgent ( );
use Apache::DBI ( );
use DBI ( );

use Carp ( );
$SIG{__WARN__} = \&Carp::cluck;

use CGI ( );
CGI->compile(':all');

Apache::DBI->connect_on_init
  ("DBI:mysql:database=test;host=localhost",
   "user", "password", {
                        PrintError => 1, # warn( ) on errors
                        RaiseError => 0, # don't die on error
                        AutoCommit => 1, # commit executes immediately
                       }
  );
1;