discourse-legacysite-perl/site/glist/templates/help/GT/AutoLoader.html
2024-06-17 22:24:05 +10:00

468 lines
12 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>GT::AutoLoader - load subroutines on demand</title>
<link rev="made" href="mailto:root@penguin.office.gossamer-threads.com" />
<style type="text/css">
/* $MVD$:fontset("Untitled Font Set 1","ARIEL","HELVETICA","HELV","SANSERIF") */
/* $MVD$:fontset("Arial","Arial") */
/* $MVD$:fontset("Arial Black","Arial Black") */
/* $MVD$:fontset("Algerian","Algerian") */
body {
background-color: white;
font-family: Verdana, Arial, sans-serif;
font-size: small;
color: black;
}
p {
background-color : white;
font-family : Verdana, Arial, sans-serif;
font-size : small;
color : black;
}
h1 {
font-family : Verdana, Arial, sans-serif;
font-weight : bold;
font-size : medium;
background-color : white;
color : maroon;
}
h2 {
font-family : Verdana, Arial, sans-serif;
font-size : medium;
font-weight : bold;
color : blue;
background-color : white;
}
h3 {
font-family : Verdana, Arial, sans-serif;
font-weight : bold;
font-size : medium;
color : black;
background-color : white;
}
h4 {
font-family : Verdana, Arial, sans-serif;
font-weight : bold;
font-size : small;
color : maroon;
background-color : white;
}
h5 {
font-family : Verdana, Arial, sans-serif;
font-weight : bold;
font-size : small;
color : blue;
background-color : white;
}
h6 {
font-family : Verdana, Arial, sans-serif;
font-weight : bold;
font-size : small;
color : black;
background-color : white;
}
ul {
font-family : Verdana, Arial, sans-serif;
font-size : small;
color : black;
}
ol {
font-family : Verdana, Arial, sans-serif;
font-size : small;
color : black;
}
dl {
font-family : Verdana, Arial, sans-serif;
font-size : small;
color : black;
}
li {
font-family : Verdana, Arial, sans-serif;
font-size : small;
color : black;
}
th {
font-family : Verdana, Arial, sans-serif;
font-size : small;
color : black;
}
td {
font-family : Verdana, Arial, sans-serif;
font-size : small;
color : black;
}
dl {
font-family : Verdana, Arial, sans-serif;
font-size : small;
color : black;
}
dd {
font-family : Verdana, Arial, sans-serif;
font-size : small;
color : black;
}
dt {
font-family : Verdana, Arial, sans-serif;
font-size : small;
color : black;
}
code {
font-family : Courier;
font-size : small;
color : black;
}
pre {
font-family : Courier;
font-size : small;
color : black;
}
.mvd-H1 {
font-family : Verdana, Arial, sans-serif;
font-weight : bold;
font-size : 14.0pt;
background-color : transparent;
background-image : none;
color : maroon;
}
.mvd-H2 {
font-family : Verdana, Arial, sans-serif;
font-size : 12.0pt;
color : blue;
}
p.indent {
font-family : "Verdana, Arial, sans-serif";
list-style-type : circle;
list-style-position : inside;
color : black;
margin-left : 16.0pt;
}
.mvd-P-indent {
font-family : Verdana, Arial, sans-serif;
list-style-type : circle;
list-style-position : inside;
color : black;
margin-left : 16.0pt;
}
pre.programlisting {
font-size : 9.0pt;
list-style-type : disc;
margin-left : 16.0pt;
margin-top : -14.0pt;
}
.mvd-PRE-programlisting {
font-size : 9.0pt;
list-style-type : disc;
margin-left : 16.0pt;
margin-top : -14.0pt;
}
.mvd-PRE {
font-size : 9.0pt;
}
p.note {
margin-left : 28.0pt;
}
.mvd-P-note {
margin-left : 28.0pt;
}
.mvd-H4 {
font-family : Verdana, Arial, sans-serif;
font-weight : normal;
font-size : 9.0pt;
color : black;
margin-left : 6.0pt;
margin-top : -14.0pt;
}
.mvd-P {
font-family : Verdana, Arial, sans-serif;
font-size : 10.0pt;
color : black;
}
.mvd-BODY {
font-family : Verdana, Arial, sans-serif;
background-color : white;
}
p.indentnobullet {
font-family : Verdana, Arial, sans-serif;
list-style-type : none;
}
.mvd-P-indentnobullet {
font-family : Verdana, Arial, sans-serif;
list-style-type : none;
}
</style>
</head>
<body style="background-color: white">
<p><a name="__index__"></a></p>
<!-- INDEX BEGIN -->
<ul>
<li><a href="#name">NAME</a></li>
<li><a href="#synopsis">SYNOPSIS</a></li>
<li><a href="#description">DESCRIPTION</a></li>
<li><a href="#use">USE</a></li>
<li><a href="#compile_all">compile_all</a></li>
<li><a href="#requirements">REQUIREMENTS</a></li>
<li><a href="#caveats">CAVEATS</a></li>
<li><a href="#maintainer">MAINTAINER</a></li>
<li><a href="#see_also">SEE ALSO</a></li>
<li><a href="#copyright">COPYRIGHT</a></li>
<li><a href="#version">VERSION</a></li>
</ul>
<!-- INDEX END -->
<hr />
<p>
</p>
<h1><a name="name">NAME</a></h1>
<p>GT::AutoLoader - load subroutines on demand</p>
<p>
</p>
<hr />
<h1><a name="synopsis">SYNOPSIS</a></h1>
<pre>
package GT::Module;
use GT::AutoLoader; # You now have an AUTOLOAD subroutine that will check for entries in %COMPILE</pre>
<p>or</p>
<pre>
package GT::OtherModule;
use GT::AutoLoader(NAME =&gt; '_AUTOLOAD'); # Import AUTOLOAD as _AUTOLOAD, define our own AUTOLOAD
sub AUTOLOAD {
...
goto &amp;_AUTOLOAD;
}</pre>
<p>then:</p>
<pre>
$COMPILE{sub} = __LINE__ . &lt;&lt;'END_OF_SUB';
sub method_name {
...
}
END_OF_SUB</pre>
<p>
</p>
<hr />
<h1><a name="description">DESCRIPTION</a></h1>
<p>The <strong>GT::AutoLoader</strong> module works as a way to speed up your code. Currently,
the only thing it does is scan for a %COMPILE hash in your package. If it finds
it, it looks for the subroutine you called, and if found compiles and runs it.</p>
<p>If unable to find a subroutine to compile in %COMPILE, <strong>GT::AutoLoader</strong> will
scan your inheritance tree (@ISA) for another AUTOLOAD subroutine to pass this
off to. If there isn't any, a fatal error occurs.</p>
<p>To use <strong>GT::AutoLoader</strong>, in its standard behaviour, simply put:
<code>use GT::AutoLoader;</code> in your module. When you use GT::AutoLoader, two things
will happen. First, an <code>AUTOLOAD</code> subroutine will be imported into your
namespace that will automatically compile your subroutines only when they are
needed, thus speeding up compile time. Secondly, a %COMPILE hash will be defined
in your package, eliminating the need for you to: use vars qw/%COMPILE/;</p>
<p>
</p>
<hr />
<h1><a name="use">USE</a></h1>
<p>You can pass options to GT::AutoLoader to change the behaviour of the module.
Currently, logging is the only option, however more options (perhaps including
a different compiling scheme) will be added at some future point.</p>
<p>Options are specified as <code>import()</code> arguments. For example:</p>
<pre>
use GT::AutoLoader(OPTION =&gt; &quot;value&quot;);</pre>
<dl>
<dt><strong><a name="item_name">NAME</a></strong><br />
</dt>
<dd>
If you want to import the autoload subroutine as something other than
'Package::AUTOLOAD', the 'NAME' option should be used. Its value is the name
to import as. For example, to import a GT::AutoLoader AUTOLOAD named _AUTOLOAD
(this is useful when declaring your own AUTOLOAD behaviour, but still using
GT::AutoLoader's behaviour as a fallback), you would do something like:
</dd>
<dd>
<pre>
use GT::AutoLoader(NAME =&gt; '_AUTOLOAD');</pre>
</dd>
<p></p>
<dt><strong><a name="item_log">LOG</a></strong><br />
</dt>
<dd>
Takes a code reference as its value. The code reference will be called three
arguments - the package name, the name of the function, and the autoload method
(Currently only 'COMPILE'). Note that this will be called for ALL autoloaded
subroutines, not just the ones in your package.
</dd>
<dd>
<p>WARNING - you cannot put code in your log that relies on autoloaded methods -
you'll end up throwing the program into an infinite loop.</p>
</dd>
<dd>
<p>For example, to get a line of debugging after each subroutine is compiled, you
could <code>use GT::AutoLoader</code> like this:</p>
</dd>
<dd>
<pre>
use GT::AutoLoader(LOG =&gt; sub {
print &quot;Compiled $_[1] in package $_[0]\n&quot;
});</pre>
</dd>
<p></p>
<dt><strong><a name="item_next">NEXT</a></strong><br />
</dt>
<dd>
Normally, GT::AutoLoader will look for another AUTOLOAD to call in your
package's @ISA inheritance tree. You can alter this behaviour and tell
GT::AutoLoader what to call next using the NEXT option.
</dd>
<dd>
<p>For example, if you have a sub _AUTOLOAD { } that you wanted to call if the
method isn't found by GT::AutoLoader, you would use GT::AutoLoader like this:</p>
</dd>
<dd>
<pre>
use GT::AutoLoader(NEXT =&gt; 'Package::Name::_AUTOLOAD');</pre>
</dd>
<dd>
<p>The _AUTOLOAD function in your package will now be called if GT::AutoLoader
can't load the method on its own. $AUTOLOAD will be set for you in whichever
package the function you provide is in. Note that if you simply want to use an
inherited AUTOLOAD, you <strong>should not</strong> use this option; GT::AutoLoader will
handle that just fine on its own.</p>
</dd>
<dd>
<p>You may omit the package (Package::Name::) if the function is in your current
package.</p>
</dd>
<p></p></dl>
<p>
</p>
<hr />
<h1><a name="compile_all">compile_all</a></h1>
<p>A function exists in GT::AutoLoader to compile all %COMPILE-subroutines. By
default (without arguments) <code>compile_all()</code> compiles every %COMPILE-subroutine in
every package that has used GT::AutoLoader. You can, however, pass in a list of
packages which <code>compile_all()</code> will check instead of compiling everything. Note
that GT::AutoLoader will only compile %COMPILE-subroutines in packages that
have used GT::AutoLoader, so if you specify package ``Foo'', but ``Foo'' hasn't
used GT::AutoLoader, it will be ignored.</p>
<p>You can do something like:</p>
<pre>
GT::AutoLoader::compile_all(__PACKAGE__) if MOD_PERL;</pre>
<p>to have a GT::AutoLoader compile every %COMPILE-subroutine in the current
package automatically under mod_perl, or you could add this code to your
mod_perl startup file or test script:</p>
<pre>
GT::AutoLoader::compile_all;</pre>
<p>Test scripts should definately use <code>compile_all()</code> to ensure that all subroutines
compile correctly!</p>
<p>
</p>
<hr />
<h1><a name="requirements">REQUIREMENTS</a></h1>
<p>None.</p>
<p>
</p>
<hr />
<h1><a name="caveats">CAVEATS</a></h1>
<p>Due to the nature of Perl's AUTOLOAD handling, you must take care when using
GT::AutoLoader in a subclass. In short, subclassed methods <strong>MUST NOT</strong> be put
into the %COMPILE hash.</p>
<p>The problem is that since the subroutine does not exist in the package, Perl,
while decending the inheritance tree, will not see it but will probably see the
parent's method (unless nothing else has called the method, but you should
never count on that), and call it rather than looking for your package's
AUTOLOAD.</p>
<p>This isn't to say that subclasses cannot use AUTOLOAD - just that subclasses
cannot use autoloaded methods (%COMPILE-subroutines) if a method of the same
name exists in the parent class. Autoloaded function calls are not affected.</p>
<p>
</p>
<hr />
<h1><a name="maintainer">MAINTAINER</a></h1>
<p>Jason Rhinelander</p>
<p>
</p>
<hr />
<h1><a name="see_also">SEE ALSO</a></h1>
<p><a href="glist.cgi?do=admin_gtdoc&topic=/GT/Base.html">the GT::Base manpage</a></p>
<p>
</p>
<hr />
<h1><a name="copyright">COPYRIGHT</a></h1>
<p>Copyright (c) 2004 Gossamer Threads Inc. All Rights Reserved.
<a href="http://www.gossamer-threads.com/">http://www.gossamer-threads.com/</a></p>
<p>
</p>
<hr />
<h1><a name="version">VERSION</a></h1>
<p>Revision: $Id: AutoLoader.pm,v 1.13 2005/03/21 06:57:58 jagerman Exp $</p>
</body>
</html>