AutoLoader - 僅在需要時載入子常式
package Foo;
use AutoLoader 'AUTOLOAD'; # import the default AUTOLOAD subroutine
package Bar;
use AutoLoader; # don't import AUTOLOAD, define our own
sub AUTOLOAD {
...
$AutoLoader::AUTOLOAD = "...";
goto &AutoLoader::AUTOLOAD;
}
AutoLoader 模組與 AutoSplit 模組和 __END__
符號一起使用,將某些子常式的載入延後到使用時,而不是一次載入所有子常式。
若要使用 AutoLoader,模組的作者必須將要自動載入的子常式定義放在 __END__
符號之後。(請參閱 perldata。)然後可以手動執行 AutoSplit 模組,將定義抽取到個別檔案 auto/funcname.al 中。
AutoLoader 實作一個 AUTOLOAD 子常式。當在 AutoLoader 的用戶端模組中呼叫未定義的子常式時,AutoLoader 的 AUTOLOAD 子常式會嘗試在與用戶端模組讀取位置相關聯的檔案中找到子常式。例如,如果 POSIX.pm 位於 /usr/local/lib/perl5/POSIX.pm 中,AutoLoader 會在 /usr/local/lib/perl5/auto/POSIX/*.al 中尋找 perl 子常式 POSIX,其中 .al
檔案與子常式同名,沒有封包。如果存在這樣的檔案,AUTOLOAD 會讀取並評估它,因此(假設)定義所需的子常式。然後,AUTOLOAD 會 goto
新定義的子常式。
此程序對特定函式完成後,該函式便會被定義,因此未來呼叫子常式時會繞過 AUTOLOAD 機制。
為了讓物件方法查詢和/或原型檢查在方法尚未定義時也能正確運作,必須「向前宣告」每個子常式(例如在 sub NAME;
中)。請參閱 perlsub 中的「SYNOPSIS」。此類向前宣告會建立「子常式 Stub」,它們是沒有程式碼的佔位符。
AutoSplit 和 AutoLoader 模組會自動建立向前宣告。AutoSplit 模組會建立一個「索引」檔案,其中包含所有 AutoSplit 子常式的向前宣告。當「使用」AutoLoader 模組時,它會將這些宣告載入呼叫者的套件。
由於此機制,因此務必始終「使用」AutoLoader,而不是「需要」它。
若要使用 AutoLoader 的 AUTOLOAD 子常式,必須 明確匯入它
use AutoLoader 'AUTOLOAD';
有些模組(主要是擴充功能)會提供自己的 AUTOLOAD 子常式。它們通常需要檢查一些特殊情況(例如常數),然後對其餘部分回退到 AutoLoader 的 AUTOLOAD。
此類模組不應匯入 AutoLoader 的 AUTOLOAD 子常式。相反地,它們應定義自己的 AUTOLOAD 子常式,如下所示
use AutoLoader;
use Carp;
sub AUTOLOAD {
my $sub = $AUTOLOAD;
(my $constname = $sub) =~ s/.*:://;
my $val = constant($constname, @_ ? $_[0] : 0);
if ($! != 0) {
if ($! =~ /Invalid/ || $!{EINVAL}) {
$AutoLoader::AUTOLOAD = $sub;
goto &AutoLoader::AUTOLOAD;
}
else {
croak "Your vendor has not defined constant $constname";
}
}
*$sub = sub { $val }; # same as: eval "sub $sub { $val }";
goto &$sub;
}
如果任何模組自己的 AUTOLOAD 子常式不需要回退到 AutoLoader 的 AUTOLOAD 子常式(因為它沒有任何 AutoSplit 子常式),則該模組根本不應使用 AutoLoader。
使用 AutoLoader 在套件主區塊中以 my
宣告的套件字彙,將不會對自動載入的子常式可見,因為給定的範圍會在 __END__
標記處結束。使用此類變數作為套件全域變數的模組,在 AutoLoader 下將無法正常運作。
vars
pragma(請參閱 "vars" in perlmod)可用於此類情況,作為明確使用套件名稱空間限定所有全域變數的替代方案。使用此 pragma 預先宣告的變數將對任何自動載入的常式可見(但遺憾的是,在套件外部並非不可見)。
您可以透過以下方式停止使用 AutoLoader
no AutoLoader;
AutoLoader 的目的類似於 SelfLoader:兩者都延遲常式的載入。
SelfLoader 使用 __DATA__
標記,而非 __END__
。雖然這避免了使用磁碟檔案層級結構,以及為每個載入的常式進行關聯的開啟/關閉,但 SelfLoader 在 __DATA__
之後一次性剖析行時會遭遇啟動速度的劣勢,之後常式會被快取。SelfLoader 也可以處理檔案中的多個套件。
AutoLoader 僅在要求時讀取程式碼,在許多情況下應該會更快,但需要像 AutoSplit 這樣的機制來建立個別檔案。如果在模組原始檔中使用 AutoLoader,ExtUtils::MakeMaker 會自動呼叫 AutoSplit。
有時,可能需要或有助於確保 AutoLoader 完全載入特定函式。例如,當您需要包裝函式來注入偵錯程式碼時,就是這種情況。在分岔之前強制提早載入程式碼,以盡可能利用寫入時複製也很有幫助。
從 AutoLoader 5.73 開始,您可以使用 AutoLoader::autoload_sub
函式,並提供要從其 .al 檔案載入的函式的完整限定名稱。其行為與您呼叫函式觸發常規 AUTOLOAD
機制完全相同,但它並未實際執行自動載入的函式。
Perl 5.002 之前的 AutoLoader 具有略微不同的介面。任何使用 AutoLoader 的舊模組都應變更為新的呼叫樣式。通常這僅表示將 require 變更為 use,視需要加入明確的 'AUTOLOAD'
匯入,並從 @ISA
中移除 AutoLoader。
在對檔案名稱長度有限制的系統上,對應於子常式的檔案可能比常式本身有較短的名稱。這可能導致檔案名稱衝突。AutoSplit 套件在用於分割模組時會警告這些潛在衝突。
在 @INC
包含相對路徑,而且程式執行 chdir
的情況下,AutoLoader 可能無法找到自動分割的檔案(甚至找到錯誤的檔案)。
SelfLoader - 不使用外部檔案的自動載入器。
AutoLoader
由 perl5-porters 維護。請將任何問題轉發至正規郵件清單。不過,任何適用於 CPAN 發行的問題都可以傳送給其維護者。
作者和維護者:Perl5-Porters <perl5-porters@perl.org>
CPAN 發行的維護者:Steffen Mueller <smueller@cpan.org>
此套件自 perl5 的第一個版本以來一直是 perl 核心的一部分。它已單獨發布至 CPAN,以便舊的安裝可以受益於錯誤修正。
此套件具有與 perl 核心相同的版權和授權
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2011, 2012, 2013
by Larry Wall and others
All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of either:
a) the GNU General Public License as published by the Free
Software Foundation; either version 1, or (at your option) any
later version, or
b) the "Artistic License" which comes with this Kit.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either
the GNU General Public License or the Artistic License for more details.
You should have received a copy of the Artistic License with this
Kit, in the file named "Artistic". If not, I'll be glad to provide one.
You should also have received a copy of the GNU General Public License
along with this program in the file named "Copying". If not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301, USA or visit their web page on the internet at
https://gnu.dev.org.tw/copyleft/gpl.html.
For those of you that choose to use the GNU General Public License,
my interpretation of the GNU General Public License is that no Perl
script falls under the terms of the GPL unless you explicitly put
said script under the terms of the GPL yourself. Furthermore, any
object code linked with perl does not automatically fall under the
terms of the GPL, provided such object code only adds definitions
of subroutines and variables, and does not otherwise impair the
resulting interpreter from executing any standard Perl script. I
consider linking in C subroutines in this manner to be the moral
equivalent of defining subroutines in the Perl language itself. You
may sell such an object file as proprietary provided that you provide
or offer to provide the Perl source, as specified by the GNU General
Public License. (This is merely an alternate way of specifying input
to the program.) You may also sell a binary produced by the dumping of
a running Perl script that belongs to you, provided that you provide or
offer to provide the Perl source as specified by the GPL. (The
fact that a Perl interpreter and your code are in the same binary file
is, in this case, a form of mere aggregation.) This is my interpretation
of the GPL. If you still have concerns or difficulties understanding
my intent, feel free to contact me. Of course, the Artistic License
spells all this out for your protection, so you may prefer to use that.