As mentioned earlier, the following library modules are arranged in alphabetical order, for easy reference.
use AnyDBM_File;
This module is a "pure virtual base class"--it has nothing of its own. It's just there to inherit from the various DBM packages. By default it inherits from NDBM_File for compatibility with earlier versions of Perl. If it doesn't find NDBM_File, it looks for DB_File, GDBM_File, SDBM_File (which is always there--it comes with Perl), and finally ODBM_File.
Perl's dbmopen function (which now exists only for backward compatibility) actually just calls tie to bind a hash to AnyDBM_File. The effect is to bind the hash to one of the specific DBM classes that AnyDBM_File inherits from.
You can override the defaults and determine which class dbmopen will tie to. Do this by redefining @ISA:
@AnyDBM_File::ISA = qw(DB_File GDBM_File NDBM_File);
Note, however, that an explicit use takes priority over the ordering of @ISA, so that:
use GDBM_File;
will cause the next dbmopen to tie your hash to GDBM_File.
You can tie hash variables directly to the desired class yourself, without using dbmopen or AnyDBM_File. For example, by using multiple DBM implementations, you can copy a database from one format to another:
use Fcntl; # for O_* values
use NDBM_File;
use DB_File;
tie %oldhash, "NDBM_File", $old_filename, O_RDWR;
tie %newhash, "DB_File", $new_filename, O_RDWR|O_CREAT|O_EXCL, 0644;
while (($key,$val) = each %oldhash) {
$newhash{$key} = $val;
}
Here's a table of the features that the different DBMish packages offer:
| Feature | ODBM | NDBM | SDBM | GDBM | BSD-DB |
|---|---|---|---|---|---|
| Linkage comes with Perl | Yes | Yes | Yes | Yes | Yes |
| Source bundled with Perl | No | No | Yes | No | No |
| Source redistributable | No | No | Yes | GPL | Yes |
| Often comes with UNIX | Yes | Yes[1] | No | No | No |
| Builds OK on UNIX | N/A | N/A | Yes | Yes | Yes[2] |
| Code size | Varies[3] | Varies[3] | Small | Big | Big |
| Disk usage | Varies[3] | Varies[3] | Small | Big | OK[4] |
| Speed | Varies[3] | Varies[3] | Slow | OK | Fast |
| FTPable | No | No | Yes | Yes | Yes |
| Easy to build | N/A | N/A | Yes | Yes | OK[5] |
| Block size limits | 1k | 4k | 1k[6] | None | None |
| Byte-order independent | No | No | No | No | Yes |
| User-defined sort order | No | No | No | No | Yes |
| Wildcard lookups | No | No | No | No | Yes |
|
Footnotes:
| |||||
Relevant library modules include: DB_File, GDBM_File, NDBM_File, ODBM_File, and SDBM_File. Related manpages: dbm (3), ndbm (3). Tied variables are discussed extensively in Chapter 5, Packages, Modules, and Object Classes, and the dbmopen entry in Chapter 3, Functions, may also be helpful. You can pick up the unbundled modules from the src/misc/ directory on your nearest CPAN site. Here are the most popular ones, but note that their version numbers may have changed by the time you read this:
package GoodStuff; use Exporter; use AutoLoader; @ISA = qw(Exporter AutoLoader);
The AutoLoader module provides a standard mechanism for delayed loading of functions stored in separate files on disk. Each file has the same name as the function (plus a .al ), and comes from a directory named after the package (with the auto/ directory). For example, the function named GoodStuff::whatever() would be loaded from the file auto/GoodStuff/whatever.al.
A module using the AutoLoader should have the special marker _ _END_ _ prior to the actual subroutine declarations. All code before this marker is loaded and compiled when the module is used. At the marker, Perl stops parsing the file.
When a subroutine not yet in memory is called, the AUTOLOAD function attempts to locate it in a directory relative to the location of the module file itself. As an example, assume POSIX.pm is located in /usr/local/lib/perl5/POSIX.pm. The AutoLoader will look for the corresponding subroutines for this package in /usr/ local/lib/perl5/auto/POSIX/*.al.
Lexicals declared with my in the main block of a package using the AutoLoader will not be visible to autoloaded functions, because the given lexical scope ends at the _ _END_ _ marker. A module using such variables as file-scoped globals will not work properly under the AutoLoader. Package globals must be used instead. When running under use strict, the use vars pragma may be employed in such situations as an alternative to explicitly qualifying all globals with the package name. Package variables predeclared with this pragma will be accessible to any autoloaded routines, but of course will not be invisible outside the module file.
The AutoLoader is a counterpart to the SelfLoader module. Both delay the loading of subroutines, but the SelfLoader accomplishes this by storing the subroutines right there in the module file rather than in separate files elsewhere. While this avoids the use of a hierarchy of disk files and the associated I/O for each routine loaded, the SelfLoader suffers a disadvantage in the one-time parsing of the lines after _ _DATA_ _, after which routines are cached. The SelfLoader can also handle multiple packages in a file.
AutoLoader, on the other hand, only reads code as it is requested, and in many cases should be faster. But it requires a mechanism like AutoSplit to be used to create the individual files.
On systems with restrictions on file name length, the file corresponding to a subroutine may have a shorter name than the routine itself. This can lead to conflicting filenames. The AutoSplit module will warn of these potential conflicts when used to split a module.
See the discussion of autoloading in Chapter 5, Packages, Modules, and Object Classes. Also see the AutoSplit module, a utility that automatically splits a module into a collection of files for autoloading.
# from a program use AutoSplit; autosplit_modules(@ARGV) # or from the command line perl -MAutoSplit -e 'autosplit(FILE, DIR, KEEP, CHECK, MODTIME)' ... # another interface perl -MAutoSplit -e 'autosplit_lib_modules(@ARGV)' ...
This function splits up your program or module into files that the AutoLoader module can handle. It is mainly used to build autoloading Perl library modules, especially complex ones like POSIX. It is used by both the standard Perl libraries and by the MakeMaker module to automatically configure libraries for autoloading.
The autosplit() interface splits the specified FILE into a hierarchy rooted at the directory DIR. It creates directories as needed to reflect class hierarchy. It then creates the file autosplit.ix, which acts as both a forward declaration for all package routines and also as a timestamp for when the hierarchy was last updated.
The remaining three arguments to autosplit() govern other options to the autosplitter. If the third argument, KEEP, is false, then any pre-existing .al files in the autoload directory are removed if they are no longer part of the module (obsoleted functions). The fourth argument, CHECK, instructs autosplit() to check the module currently being split to ensure that it really does include a use specification for the AutoLoader module, and skips the module if AutoLoader is not detected. Lastly, the MODTIME argument specifies that autosplit() is to check the modification time of the module against that of the autosplit.ix file, and only split the module if it is newer.
Here's a typical use of AutoSplit by the MakeMaker utility via the command line:
perl -MAutoSplit -e 'autosplit($ARGV[0], $ARGV[1], 0, 1, 1)'
MakeMaker defines this as a make macro, and it is invoked with file and directory arguments. The autosplit() function splits the named file into the given directory and deletes obsolete .al files, after checking first that the module does use the AutoLoader and ensuring that the module isn't already split in its current form.
The autosplit_lib_modules() form is used in the building of Perl. It takes as input a list of files (modules) that are assumed to reside in a directory lib/ relative to the current directory. Each file is sent to the autosplitter one at a time, to be split into the directory lib/auto/.
In both usages of the autosplitter, only subroutines defined following the Perl special marker _ _END_ _ are split out into separate files. Routines placed prior to this marker are not autosplit, but are forced to load when the module is first required.
Currently, AutoSplit cannot handle multiple package specifications within one file.
AutoSplit will inform the user if it is necessary to create the top-level directory specified in the invocation. It's better if the script or installation process that invokes AutoSplit has created the full directory path ahead of time. This warning may indicate that the module is being split into an incorrect path.
AutoSplit will also warn the user of subroutines whose names cause potential naming conflicts on machines with severely limited (eight characters or less) filename length. Since the subroutine name is used as the filename, these warnings can aid in portability to such systems.
Warnings are issued and the file skipped if AutoSplit cannot locate either the _ _END_ _ marker or a specification of the form package Name;. AutoSplit will also complain if it can't create directories or files.
use Benchmark;
# timeit(): run $count iterations of the given Perl code, and time it
$t = timeit($count, 'CODE'); # $t is now a Benchmark object
# timestr(): convert Benchmark times to printable strings
print "$count loops of 'CODE' took:", timestr($t), "\n";
# timediff(): calculate the difference between two times
$t = timediff($t1 - $t2);
# timethis(): run "code" $count times with timeit(); also, print out a
# header saying "timethis $count: "
$t = timethis($count, "CODE");
# timethese(): run timethis() on multiple chunks of code
@t = timethese($count, {
'Name1' => '...CODE1...',
'Name2' => '...CODE2...',
});
# new method: return the current time
$t0 = new Benchmark;
# ... your CODE here ...
$t1 = new Benchmark;
$td = timediff($t1, $t0);
print "the code took: ", timestr($td), "\n";
# debug method: enable or disable debugging
Benchmark->debug (1);
$t = timeit(10, ' 5 ** $Global ');
Benchmark->debug(0);
The Benchmark module encapsulates a number of routines to help you figure out how long it takes to execute some code a given number of times within a loop.
For the timeit() routine, $count is the number of times to run the loop. CODE is a string containing the code to run. timeit() runs a null loop with $count iterations, and then runs the same loop with your code inserted. It reports the difference between the times of execution.
For timethese(), a loop of $count iterations is run on each code chunk separately, and the results are reported separately. The code to run is given as a hash with keys that are names and values that are code. timethese() is handy for quick tests to determine which way of doing something is faster. For example:
$ perl -MBenchmark -Minteger
timethese(100000, { add => '$i += 2', inc => '$i++; $i++' });
_ _END_ _
Benchmark: timing 1000000 iterations of add, inc...
add: 4 secs ( 4.52 usr 0.00 sys = 4.52 cpu)
inc: 6 secs ( 5.32 usr 0.00 sys = 5.32 cpu)
The following routines are exported into your namespace if you use the Benchmark module:
timeit() timethis() timethese() timediff() timestr()
The following routines will be exported into your namespace if you specifically ask that they be imported:
clearcache() # clear just the cache element indexed by $key clearallcache() # clear the entire cache disablecache() # do not use the cache enablecache() # resume caching
Code is executed in the caller's package.
The null loop times are cached, the key being the number of iterations. You can control caching with calls like these:
clearcache($key); clearallcache(); disablecache(); enablecache();
Benchmark inherits only from the Exporter class.
The elapsed time is measured using time (2) and the granularity is therefore only one second. Times are given in seconds for the whole loop (not divided by the number of iterations). Short tests may produce negative figures because Perl can appear to take longer to execute the empty loop than a short test.
The user and system CPU time is measured to millisecond accuracy using times (3). In general, you should pay more attention to the CPU time than to elapsed time, especially if other processes are running on the system. Also, elapsed times of five seconds or more are needed for reasonable accuracy.
Because you pass in a string to be evaled instead of a closure to be executed, lexical variables declared with my outside of the eval are not visible.
use Carp; carp "Be careful!"; # warn of errors (from perspective of caller) croak "We're outta here!"; # die of errors (from perspective of caller) confess "Bye!"; # die of errors with stack backtrace
carp() and croak() behave like warn and die, respectively, except that they report the error as occurring not at the line of code where they are invoked, but at a line in one of the calling routines. Suppose, for example, that you have a routine goo() containing an invocation of carp(). In that case--and assuming that the current stack shows no callers from a package other than the current one--carp() will report the error as occurring where goo() was called. If, on the other hand, callers from different packages are found on the stack, then the error is reported as occurring in the package immediately preceding the package in which the carp() invocation occurs. The intent is to let library modules act a little more like built-in functions, which always report errors where you call them from.
confess() is like die except that it prints out a stack backtrace. The error is reported at the line where confess() is invoked, not at a line in one of the calling routines.
use Config;
if ($Config{cc} =~ /gcc/) {
print "built by gcc\n";
}
use Config qw(myconfig config_sh config_vars);
print myconfig();
print config_sh();
config_vars(qw(osname archname));
The Config module contains all the information that the Configure script had to figure out at Perl build time (over 450 values).[1]
[1] Perl was written in C, not because it's a portable language, but because it's a ubiquitous language. A bare C program is about as portable as Chuck Yeager on foot.
Shell variables from the config.sh file (written by Configure) are stored in a readonly hash, %Config, indexed by their names. Values set to the string "undef" in config.sh are returned as undefined values. The Perl exists function should be used to check whether a named variable exists.
Returns a textual summary of the major Perl configuration values. See also the explanation of Perl's -V command-line switch in Chapter 6, Social Engineering.
Returns the entire Perl configuration information in the form of the original config.sh shell variable assignment script.
Prints to STDOUT the values of the named configuration variables. Each is printed on a separate line in the form:
name='value';
Names that are unknown are output as name='UNKNOWN';.
Here's a more sophisticated example using %Config:
use Config;
defined $Config{sig_name} or die "No sigs?";
foreach $name (split(' ', $Config{sig_name})) {
$signo{$name} = $i;
$signame[$i] = $name;
$i++;
}
print "signal #17 = $signame[17]\n";
if ($signo{ALRM}) {
print "SIGALRM is $signo{ALRM}\n";
}
Because configuration information is not stored within the Perl executable itself, it is possible (but unlikely) that the information might not relate to the actual Perl binary that is being used to access it. The Config module checks the Perl version number when loaded to try to prevent gross mismatches, but can't detect subsequent rebuilds of the same version.
use Cwd;
$dir = cwd(); # get current working directory safest way
$dir = getcwd(); # like getcwd(3) or getwd(3)
$dir = fastcwd(); # faster and more dangerous
use Cwd 'chdir'; # override chdir; keep PWD up to date
chdir "/tmp";
print $ENV{PWD}; # prints "/tmp"
cwd() gets the current working directory using the most natural and safest form for the current architecture. For most systems it is identical to `pwd` (but without the trailing line terminator).
getcwd() does the same thing by re-implementing getcwd (3) or getwd (3) in Perl.
fastcwd() looks the same as getcwd(), but runs faster. It's also more dangerous because you might chdir out of a directory that you can't chdir back into.
It is recommended that one of these functions be used in all code to ensure portability because the pwd program probably only exists on UNIX systems.
If you consistently override your chdir built-in function in all packages of your program, then your PWD environment variable will automatically be kept up to date. Otherwise, you shouldn't rely on it. (Which means you probably shouldn't rely on it.)
use DB_File; # brackets in following code indicate optional arguments [$X =] tie %hash, "DB_File", $filename [, $flags, $mode, $DB_HASH]; [$X =] tie %hash, "DB_File", $filename, $flags, $mode, $DB_BTREE; [$X =] tie @array, "DB_File", $filename, $flags, $mode, $DB_RECNO; $status = $X->del($key [, $flags]); $status = $X->put($key, $value [, $flags]); $status = $X->get($key, $value [, $flags]); $status = $X->seq($key, $value [, $flags]); $status = $X->sync([$flags]); $status = $X->fd; untie %hash; untie @array;
DB_File is the most flexible of the DBM-style tie modules. It allows Perl programs to make use of the facilities provided by Berkeley DB (not included). If you intend to use this module you should really have a copy of the Berkeley DB manual page at hand. The interface defined here mirrors the Berkeley DB interface closely.
Berkeley DB is a C library that provides a consistent interface to a number of database formats. DB_File provides an interface to all three of the database (file) types currently supported by Berkeley DB.
The file types are:
Allows arbitrary key/data pairs to be stored in data files. This is equivalent to the functionality provided by other hashing packages like DBM, NDBM, ODBM, GDBM, and SDBM. Remember, though, the files created using DB_HASH are not binary compatible with any of the other packages mentioned. A default hashing algorithm that will be adequate for most applications is built into Berkeley DB. If you do need to use your own hashing algorithm, it's possible to write your own and have DB_File use it instead.
The btree format allows arbitrary key/data pairs to be stored in a sorted, balanced binary tree. It is possible to provide a user-defined Perl routine to perform the comparison of keys. By default, though, the keys are stored in lexical order. This is useful for providing an ordering for your hash keys, and may be used on hashes that are only in memory and never go to disk.
DB_RECNO allows both fixed-length and variable-length flat text files to be manipulated using the same key/value pair interface as in DB_HASH and DB_BTREE. In this case the key will consist of a record (line) number.
DB_File gives access to Berkeley DB files using Perl's tie function. This allows DB_File to access Berkeley DB files using either a hash (for DB_HASH and DB_BTREE file types) or an ordinary array (for the DB_RECNO file type).
In addition to the tie interface, it is also possible to use most of the functions provided in the Berkeley DB API.
Berkeley DB uses the function dbopen (3) to open or create a database. Below is the C prototype for dbopen (3).
DB *
dbopen (const char *file, int flags, int mode,
DBTYPE type, const void *openinfo)
The type parameter is an enumeration selecting one of the three interface methods, DB_HASH, DB_BTREE or DB_RECNO. Depending on which of these is actually chosen, the final parameter, openinfo, points to a data structure that allows tailoring of the specific interface method.
This interface is handled slightly differently in DB_File. Here is an equivalent call using DB_File.
tie %array, "DB_File", $filename, $flags, $mode, $DB_HASH;
The filename, flags, and mode parameters are the direct equivalent of their dbopen (3) counterparts. The final parameter $DB_HASH performs the function of both the type and openinfo parameters in dbopen (3).
In the example above $DB_HASH is actually a reference to a hash object. DB_File has three of these predefined references. Apart from $DB_HASH, there are also $DB_BTREE and $DB_RECNO.
The keys allowed in each of these predefined references are limited to the names used in the equivalent C structure. So, for example, the $DB_HASH reference will only allow keys called bsize, cachesize, ffactor, hash, lorder, and nelem.
To change one of these elements, just assign to it like this:
$DB_HASH->{cachesize} = 10_000;
In order to make RECNO more compatible with Perl, the array offset for all RECNO arrays begins at 0 rather than 1 as in Berkeley DB.
Berkeley DB allows the creation of in-memory databases by using NULL (that is, a (char *)0 in C) in place of the filename. DB_File uses undef instead of NULL to provide this functionality.
use strict;
use Fcntl;
use DB_File;
my ($k, $v, %hash);
tie(%hash, 'DB_File', undef, O_RDWR|O_CREAT, 0, $DB_BTREE)
or die "can't tie DB_File: $!":
foreach $k (keys %ENV) {
$hash{$k} = $ENV{$k};
}
# this will now come out in sorted lexical order
# without the overhead of sorting the keys
while (($k,$v) = each %hash) {
print "$k=$v\n";
}
In addition to accessing Berkeley DB using a tied hash or array, you can also make direct use of most functions defined in the Berkeley DB documentation.
To do this you need to remember the return value from tie, or use the tied function to get at it yourself later on.
$db = tie %hash, "DB_File", "filename";
Once you have done that, you can access the Berkeley DB API functions directly.
$db->put($key, $value, R_NOOVERWRITE); # invoke the DB "put" function
All the functions defined in the dbopen (3) manpage are available except for close() and dbopen() itself. The DB_File interface to these functions mirrors the way Berkeley DB works. In particular, note that all these functions return only a status value. Whenever a Berkeley DB function returns data via one of its parameters, the DB_File equivalent does exactly the same thing.
All the constants defined in the dbopen manpage are also available.
Below is a list of the functions available. (The comments only tell you the differences from the C version.)
The $flags parameter is optional. The value associated with the key you request is returned in the $value parameter.
As usual the flags parameter is optional. If you use either the R_IAFTER or R_IBEFORE flags, the $key parameter will be set to the record number of the inserted key/value pair.
The $flags parameter is optional.
No differences encountered.
The $flags parameter is optional. Both the $key and $value parameters will be set.
The $flags parameter is optional.
Here are a few examples. First, using $DB_HASH:
use DB_File;
use Fcntl;
tie %h, "DB_File", "hashed", O_RDWR|O_CREAT, 0644, $DB_HASH;
# Add a key/value pair to the file
$h{apple} = "orange";
# Check for value of a key
print "No, we have some bananas.\n" if $h{banana};
# Delete
delete $h{"apple"};
untie %h;
Here is an example using $DB_BTREE. Just to make life more interesting, the default comparison function is not used. Instead, a Perl subroutine, Compare(), does a case-insensitive comparison.
use DB_File;
use Fcntl;
sub Compare {
my ($key1, $key2) = @_;
"\L$key1" cmp "\L$key2";
}
$DB_BTREE->{compare} = 'Compare';
tie %h, 'DB_File', "tree", O_RDWR|O_CREAT, 0644, $DB_BTREE;
# Add a key/value pair to the file
$h{Wall} = 'Larry';
$h{Smith} = 'John';
$h{mouse} = 'mickey';
$h{duck} = 'donald';
# Delete
delete $h{duck};
# Cycle through the keys printing them in order.
# Note it is not necessary to sort the keys as
# the btree will have kept them in order automatically.
while ($key = each %h) { print "$key\n" }
untie %h;
The preceding code yields this output:
mouse Smith Wall
Next, an example using $DB_RECNO. You may access a regular textfile as an array of lines. But the first line of the text file is the zeroth element of the array, and so on. This provides a clean way to seek to a particular line in a text file.
my(@line, $number);
$number = 10;
use Fcntl;
use DB_File;
tie(@line, "DB_File", "/tmp/text", O_RDWR|O_CREAT, 0644, $DB_RECNO)
or die "can't tie file: $!";
$line[$number - 1] = "this is a new line $number";
Here's an example of updating a file in place:
use Fcntl;
use DB_File;
tie(@file, 'DB_File', "/tmp/sample", O_RDWR, 0644, $DB_RECNO)
or die "can't update /tmp/sample: $!";
print "line #3 was ", $file[2], "\n";
$file[2] = `date`;
untie @file;
Note that the tied array interface is incomplete, causing some operations on the resulting array to fail in strange ways. See the discussion of tied arrays in Chapter 5, Packages, Modules, and Object Classes. Some object methods are provided to avoid this. Here's an example of reading a file backward:
use DB_File;
use Fcntl;
$H = tie(@h, "DB_File", $file, O_RDWR, 0640, $DB_RECNO)
or die "Cannot open file $file: $!\n";
# print the records in reverse order
for ($i = $H->length - 1; $i >= 0; --$i) {
print "$i: $h[$i]\n";
}
untie @h;
Concurrent access of a read-write database by several parties requires that each use some kind of locking. Here's an example that uses the fd() method to get the file descriptor, and then a careful open to give something Perl will flock for you. Run this repeatedly in the background to watch the locks granted in proper order. You have to call the sync() method to ensure that the writes make it to disk between access, or else the library would normally hold some in its own cache.
use Fcntl; use DB_File;
use strict;
sub LOCK_SH { 1 }
sub LOCK_EX { 2 }
sub LOCK_NB { 4 }
sub LOCK_UN { 8 }
my($oldval, $fd, $db_obj, %db_hash, $value, $key);
$key = shift || 'default'; $value = shift || 'magic';
$value .= " $$";
$db_obj = tie(%db_hash, 'DB_File', '/tmp/foo.db', O_CREAT|O_RDWR, 0644)
or die "dbcreat /tmp/foo.db $!";
$fd = $db_obj->fd;
print "$$: db fd is $fd\n";
open(DB_FH, "+<&=$fd") or die "fdopen $!";
unless (flock (DB_FH, LOCK_SH | LOCK_NB)) {
print "$$: CONTENTION; can't read during write update!
Waiting for read lock ($!) ....";
unless (flock (DB_FH, LOCK_SH)) { die "flock: $!" }
}
print "$$: Read lock granted\n";
$oldval = $db_hash{$key};
print "$$: Old value was $oldval\n";
flock(DB_FH, LOCK_UN);
unless (flock (DB_FH, LOCK_EX | LOCK_NB)) {
print "$$: CONTENTION; must have exclusive lock!
Waiting for write lock ($!) ....";
unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" }
}
print "$$: Write lock granted\n";
$db_hash{$key} = $value;
sleep 10;
$db_obj->sync(); # to flush
flock(DB_FH, LOCK_UN);
untie %db_hash;
undef $db_obj; # removing the last reference to the DB
# closes it. Closing DB_FH is implicit.
print "$$: Updated db to $key=$value\n";
Related manpages: dbopen (3), hash (3), recno (3), btree (3).
Berkeley DB is available from these locations:
use Devel::SelfStubber; $modulename = "Mystuff::Grok"; # no .pm suffix or slashes $lib_dir = ""; # defaults to current directory Devel::SelfStubber->stub($modulename, $lib_dir); # stubs only # to generate the whole module with stubs inserted correctly use Devel::SelfStubber; $Devel::SelfStubber::JUST_STUBS = 0; Devel::SelfStubber->stub($modulename, $lib_dir);
Devel::SelfStubber supports inherited, autoloaded methods by printing the stubs you need to put in your module before the _ _DATA_ _ token. A subroutine stub looks like this:
sub moo;
The stub ensures that if a method is called, it will get loaded. This is best explained using the following example:
Assume four classes, A, B, C, and D. A is the root class, B is a subclass of A, C is a subclass of B, and D is another subclass of A.
A
/ \
B D
/
C
If D calls an autoloaded method moo() which is defined in class A, then the method is loaded into class A, and executed. If C then calls method moo(), and that method was reimplemented in class B, but set to be autoloaded, then the lookup mechanism never gets to the AUTOLOAD mechanism in B because it first finds the moo() method already loaded in A, and so erroneously uses that. If the method moo() had been stubbed in B, then the lookup mechanism would have found the stub, and correctly loaded and used the subroutine from B.
So, to get autoloading to work right with classes and subclasses, you need to make sure the stubs are loaded.
The SelfLoader can load stubs automatically at module initialization with:
SelfLoader->load_stubs();
But you may wish to avoid having the stub-loading overhead associated with your initialization.[2] In this case, you can put the subroutine stubs before the _ _DATA_ _ token. This can be done manually, by inserting the output of the first call to the stub() method above. But the module also allows automatic insertion of the stubs. By default the stub() method just prints the stubs, but you can set the global $Devel::SelfStubber::JUST_STUBS to 0 and it will print out the entire module with the stubs positioned correctly, as in the second call to stub().
[2] Although note that the load_stubs() method will be called sooner or later, at latest when the first subroutine is being autoloaded--which may be too late, if you're trying to moo().
At the very least, this module is useful for seeing what the SelfLoader thinks are stubs; in order to ensure that future versions of the SelfStubber remain in step with the SelfLoader, the SelfStubber actually uses the SelfLoader to determine which stubs are needed.
# As a pragma: use diagnostics; use diagnostics -verbose; enable diagnostics; disable diagnostics; # As a program: $ perl program 2>diag.out $ splain [-v] [-p] diag.out
The diagnostics module extends the terse diagnostics normally emitted by both the Perl compiler and the Perl interpreter, augmenting them with the more explicative and endearing descriptions found in Chapter 9, Diagnostic Messages. It affects the compilation phase of your program rather than merely the execution phase.
To use in your program as a pragma, merely say:
use diagnostics;
at the start (or near the start) of your program. (Note that this enables Perl's -w flag.) Your whole compilation will then be subject to the enhanced diagnostics. These are still issued to STDERR.
Due to the interaction between run-time and compile-time issues, and because it's probably not a very good idea anyway, you may not use:
no diagnostics
to turn diagnostics off at compile time. However, you can turn diagnostics on or off at run-time by invoking diagnostics::enable() and diagnostics::disable(), respectively.
The -verbose argument first prints out the perldiag (1) manpage introduction before any other diagnostics. The $diagnostics::PRETTY variable, if set in a BEGIN block, results in nicer escape sequences for pagers:
BEGIN { $diagnostics::PRETTY = 1 }
While apparently a whole other program, splain is actually nothing more than a link to the (executable) diagnostics.pm module. It acts upon the standard error output of a Perl program, which you may have treasured up in a file, or piped directly to splain.
The -v flag has the same effect as:
use diagnostics -verbose
The -p flag sets $diagnostics::PRETTY to true. Since you're post-processing with splain, there's no sense in being able to enable() or disable() diagnostics.
Output from splain (unlike the pragma) is directed to STDOUT.
The following file is certain to trigger a few errors at both run-time and compile-time:
use diagnostics; print NOWHERE "nothing\n"; print STDERR "\n\tThis message should be unadorned.\n"; warn "\tThis is a user warning"; print "\nDIAGNOSTIC TESTER: Please enter a <CR> here: "; my $a, $b = scalar <STDIN>; print "\n"; print $x/$y;
If you prefer to run your program first and look at its problems afterward, do this while talking to a Bourne-like shell:
perl -w test.pl 2>test.out ./splain < test.out
If you don't want to modify your source code, but still want on-the-fly warnings, do this:
perl -w -Mdiagnostics test.pl
If you want to control warnings on the fly, do something like this. (Make sure the use comes first, or you won't be able to get at the enable() or disable() methods.)
use diagnostics; # checks entire compilation phase print "\ntime for 1st bogus diags: SQUAWKINGS\n"; print BOGUS1 'nada'; print "done with 1st bogus\n"; disable diagnostics; # only turns off run-time warnings print "\ntime for 2nd bogus: (squelched)\n"; print BOGUS2 'nada'; print "done with 2nd bogus\n"; enable diagnostics; # turns back on run-time warnings print "\ntime for 3rd bogus: SQUAWKINGS\n"; print BOGUS3 'nada'; print "done with 3rd bogus\n"; disable diagnostics; print "\ntime for 4th bogus: (squelched)\n"; print BOGUS4 'nada'; print "done with 4th bogus\n";
use DirHandle;
my $d = new DirHandle "."; # open the current directory
if (defined $d) {
while (defined($_ = $d->read)) { something($_); }
$d->rewind;
while (defined($_ = $d->read)) { something_else($_); }
}
DirHandle provides an alternative interface to Perl's opendir, closedir, readdir, and rewinddir functions.
The only objective benefit to using DirHandle is that it avoids name-space pollution by creating anonymous globs to hold directory handles. Well, and it also closes the DirHandle automatically when the last reference goes out of scope. But since most people only keep a directory handle open long enough to slurp in all the filenames, this is of dubious value. But hey, it's object-oriented.
package YourModule; require DynaLoader; @ISA = qw(... DynaLoader ...); bootstrap YourModule;
This module defines the standard Perl interface to the dynamic linking mechanisms available on many platforms. A common theme throughout the module system is that using a module should be easy, even if the module itself (or the installation of the module) is more complicated as a result. This applies particularly to the DynaLoader. To use it in your own module, all you need are the incantations listed above in the synopsis. This will work whether YourModule is statically or dynamically linked into Perl. (This is a Configure option for each module.) The bootstrap() method will either call YourModule's bootstrap routine directly if YourModule is statically linked into Perl, or if not, YourModule will inherit the bootstrap() method from DynaLoader, which will do everything necessary to load in your module, and then call YourModule's bootstrap() method for you, as if it were there all the time and you called it yourself. Piece of cake, of the have-it-and-eat-it-too variety.
The rest of this description talks about the DynaLoader from the viewpoint of someone who wants to extend the DynaLoader module to a new architecture. The Configure process selects which kind of dynamic loading to use by choosing to link in one of several C implementations, which must be linked into perl statically. (This is unlike other C extensions, which provide a single implementation, which may be linked in either statically or dynamically.)
The DynaLoader is designed to be a very simple, high-level interface that is sufficiently general to cover the requirements of SunOS, HP-UX, NeXT, Linux, VMS, Win-32, and other platforms. By itself, though, DynaLoader is practically useless for accessing non-Perl libraries because it provides almost no Perl-to-C "glue". There is, for example, no mechanism for calling a C library function or supplying its arguments in any sort of portable form. This job is delegated to the other extension modules that you may load in by using DynaLoader.
Variables:
@dl_library_path
@dl_resolve_using
@dl_require_symbols
$dl_debug
Subroutines:
bootstrap($modulename);
@filepaths = dl_findfile(@names);
$filepath = dl_expandspec($spec);
$libref = dl_load_file($filename);
$symref = dl_find_symbol($libref, $symbol);
@symbols = dl_undef_symbols();
dl_install_xsub($name, $symref [, $filename]);
$message = dl_error;
The bootstrap() and dl_findfile() routines are standard across all platforms, and so are defined in DynaLoader.pm. The rest of the functions are supplied by the particular .xs file that supplies the implementation for the platform. (You can examine the existing implementations in the ext/DynaLoader/ *.xs files in the Perl source directory. You should also read DynaLoader.pm, of course.) These implementations may also tweak the default values of the variables listed below.
The default list of directories in which dl_findfile() will search for libraries. Directories are searched in the order they are given in this array variable, beginning with subscript 0. @dl_library_path is initialized to hold the list of "normal" directories (/usr/lib and so on) determined by the Perl installation script, Configure, and given by $Config{'libpth'}. This is to ensure portability across a wide range of platforms. @dl_library_path should also be initialized with any other directories that can be determined from the environment at run-time (such as LD_LIBRARY_PATH for SunOS). After initialization, @dl_library_path can be manipulated by an application using push and unshift before calling dl_findfile(). unshift can be used to add directories to the front of the search order either to save search time or to override standard libraries with the same name. The load function that dl_load_file() calls might require an absolute pathname. The dl_findfile() function and @dl_library_path can be used to search for and return the absolute pathname for the library/object that you wish to load.
A list of additional libraries or other shared objects that can be used to resolve any undefined symbols that might be generated by a later call to dl_load_file(). This is only required on some platforms that do not handle dependent libraries automatically. For example, the Socket extension shared library (auto/Socket/Socket.so) contains references to many socket functions that need to be resolved when it's loaded. Most platforms will automatically know where to find the "dependent" library (for example, /usr/lib/libsocket.so). A few platforms need to be told the location of the dependent library explicitly. Use @dl_resolve_using for this. Example:
@dl_resolve_using = dl_findfile('-lsocket');
A list of one or more symbol names that are in the library/object file to be dynamically loaded. This is only required on some platforms.
$message = dl_error();
Error message text from the last failed DynaLoader function. Note that, similar to errno in UNIX, a successful function call does not reset this message. Implementations should detect the error as soon as it occurs in any of the other functions and save the corresponding message for later retrieval. This will avoid problems on some platforms (such as SunOS) where the error message is very temporary (see, for example, dlerror (3)).
Internal debugging messages are enabled when $dl_debug is set true. Currently, setting $dl_debug only affects the Perl side of the DynaLoader. These messages should help an application developer to resolve any DynaLoader usage problems. $dl_debug is set to $ENV{'PERL_DL_DEBUG'} if defined. For the DynaLoader developer and porter there is a similar debugging variable added to the C code (see dlutils.c) and enabled if Perl was built with the -DDEBUGGING flag. This can also be set via the PERL_DL_DEBUG environment variable. Set to 1 for minimal information or higher for more.
@filepaths = dl_findfile(@names)
Determines the full paths (including file suffix) of one or more loadable files, given their generic names and optionally one or more directories. Searches directories in @dl_library_path by default and returns an empty list if no files were found. Names can be specified in a variety of platform-independent forms. Any names in the form -lname are converted into libname.*, where .* is an appropriate suffix for the platform. If a name does not already have a suitable prefix or suffix, then the corresponding file will be sought by trying prefix and suffix combinations appropriate to the platform: $name.o, lib$name.* and $name. If any directories are included in @names, they are searched before @dl_library_path. Directories may be specified as -Ldir. Any other names are treated as filenames to be searched for. Using arguments of the form -Ldir and -lname is recommended. Example:
@dl_resolve_using = dl_findfile(qw(-L/usr/5lib -lposix));
$filepath = dl_expandspec($spec)
Some unusual systems such as VMS require