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" [email protected] < 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.
Copyright © 2001 O'Reilly & Associates. All rights reserved.