目錄

名稱

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 機制。

子常式 Stub

為了讓物件方法查詢和/或原型檢查在方法尚未定義時也能正確運作,必須「向前宣告」每個子常式(例如在 sub NAME; 中)。請參閱 perlsub 中的「SYNOPSIS」。此類向前宣告會建立「子常式 Stub」,它們是沒有程式碼的佔位符。

AutoSplit 和 AutoLoader 模組會自動建立向前宣告。AutoSplit 模組會建立一個「索引」檔案,其中包含所有 AutoSplit 子常式的向前宣告。當「使用」AutoLoader 模組時,它會將這些宣告載入呼叫者的套件。

由於此機制,因此務必始終「使用」AutoLoader,而不是「需要」它。

使用 AutoLoader 的 AUTOLOAD 子常式

若要使用 AutoLoader 的 AUTOLOAD 子常式,必須 明確匯入它

use AutoLoader 'AUTOLOAD';

覆寫 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

您可以透過以下方式停止使用 AutoLoader

no AutoLoader;

AutoLoaderSelfLoader

AutoLoader 的目的類似於 SelfLoader:兩者都延遲常式的載入。

SelfLoader 使用 __DATA__ 標記,而非 __END__。雖然這避免了使用磁碟檔案層級結構,以及為每個載入的常式進行關聯的開啟/關閉,但 SelfLoader__DATA__ 之後一次性剖析行時會遭遇啟動速度的劣勢,之後常式會被快取。SelfLoader 也可以處理檔案中的多個套件。

AutoLoader 僅在要求時讀取程式碼,在許多情況下應該會更快,但需要像 AutoSplit 這樣的機制來建立個別檔案。如果在模組原始檔中使用 AutoLoaderExtUtils::MakeMaker 會自動呼叫 AutoSplit

強制 AutoLoader 載入函式

有時,可能需要或有助於確保 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.