If you invoke a function called
Test::func()
, for example, and if
func()
has not been defined in module Test, Perl automatically looks for a subroutine called
Test::AUTOLOAD()
. If such a subroutine exists, Perl calls it with the arguments that were passed to
func()
. In addition, a variable called
$AUTOLOAD
is set to the full name of the function that was called ("
Test::func
"). Objective-C programmers will recognize this as being similar to the ":forward" declaration, in which an object uses this statement to trap all procedure calls it doesn't handle, in order to forward it to a "delegate."
The
AUTOLOAD
subroutine can do just about anything it wants. For example, it can do one of the following:
-
Handle the call itself. The caller of Test::func does not know that
AUTOLOAD
really handled the call.
-
Automatically create a subroutine on the fly (using
eval
) to do the right thing, and then call that new subroutine. In fact, instead of
calling
that subroutine, you can simply go to it, like this:
sub AUTOLOAD {
... create subroutine ...
goto &$AUTOLOAD; # jump to it
}
This is a special form of
goto
that erases the stack-frame of the
AUTOLOAD
routine so that Test::func will not know it has been being called from
AUTOLOAD
.
-
Dynamically load an object file (or a DLL in Microsoft Windows), using the standard Dynaloader module, and then execute the appropriate call. This is one of the more popular uses of
AUTOLOAD
.
-
Use the
system
function to launch another program by the same name.
Shell.pm
in your Perl library is the really fancy version of this facility. Here is a simplified version:
#------------------------------------------------------------------
package Shell;
#------------------------------------------------------------------
sub AUTOLOAD {
my($program) = $AUTOLOAD;
# We are just interested in the command name, not in
# the package name
$program =~ s/^.*:://;
system ("$program @_");
}
#------------------------------------------------------------------
use Shell;
ls ('-lR'); # Triggers a call to AUTOLOAD since sub ls() doesn't exist
mail ('-s "This is a test" joe@foo.com < letter.txt');
Autoloading can also be used to delay the loading of subroutines until they are absolutely necessary. A module called
Autosplit (in the standard distribution) is used to split a module into multiple modules, each with one subroutine from the original, and the Autoloader module can subsequently be used to subsequently load only the file corresponding to the called subroutine.