目錄

名稱

SelfLoader - 僅在需要時加載函數

用法

package FOOBAR;
use SelfLoader;

... (initializing code)

__DATA__
sub {....

描述

此模組告訴其用戶,FOOBAR 包中的函數將從 __DATA__ 標記後自動加載。另請參閱 perlsub 中的「自動加載」

__DATA__ 標記

__DATA__ 標記告訴 perl 編譯器,編譯 perl 代碼已完成。 __DATA__ 標記後的所有內容可通過文件處理程序 FOOBAR::DATA 進行讀取,其中 FOOBAR 是達到 __DATA__ 標記時的當前包的名稱。這與包 'main' 中的 __END__ 的作用相同,但對於其他模塊,__END__ 後的數據不會自動檢索,而 __DATA__ 後的數據則會。在 5.001m 之前的 perl 版本中不會識別 __DATA__ 標記。

請注意,同一個套件中的多個檔案可能包含__DATA__標記,而編譯器遇到的給定套件中的最後一個__DATA__標記是文件處理器可存取的標記。這也適用於__END__和主程式,也就是說,如果「main」程式有一個__END__,但是被該程式「require」(而非「use」)的模組有一個「package main;」聲明,後跟一個__DATA__,那麼DATA文件處理器將設置為存取模組中__DATA__後的數據,而不是「main」程式中__END__標記後的數據,因為編譯器稍後遇到了「require」的文件。

SelfLoader 自動載入

SelfLoader 的工作方式是,使用者將__DATA__標記放置在需要在「require」時編譯和執行的 Perl 代碼之後,但是在之後可能被加載的子程序聲明之前 - 通常是因為它們可能永遠不會被調用。

SelfLoader 將從 FOOBAR::DATA 文件處理器讀取以加載__DATA__後的數據,並在調用時加載任何子程序。成本是__DATA__後數據的一次性解析,以及任何自動載入函數的首次調用的加載延遲。好處(希望如此)是加速編譯階段,無需加載從不使用的函數。

SelfLoader 將在遇到__END__標記時停止從__DATA__讀取 - 正如您所期望的那樣。如果存在__END__標記,並且其後跟著標記 DATA,則SelfLoader 將在該標記之後的行上保留 FOOBAR::DATA 文件處理器。

SelfLoaderAUTOLOAD子程序導出到使用SelfLoader的套件中,並在首次調用時加載所呼叫的子程序。

將始終被調用的子程序放在__DATA__標記後並沒有好處。

自動載入和套件語義

「my $pack_lexical」聲明使變量$pack_lexical僅在__DATA__標記之前的文件中局部化。在其他地方聲明的子程序無法看到這些類型的變量,就像在包中聲明但在另一個文件中聲明子程序一樣,它們無法看到這些變量。

具體而言,自動載入的函數無法看到套件語義(這適用於SelfLoader和Autoloader)。vars pragma 提供了一種定義將對自動載入例程可見的包級全局變量的替代方法。請參閱perlmod中「pragma」部分中關於vars的文檔。

SelfLoader 和 AutoLoader

SelfLoader可以取代AutoLoader - 只需將'use AutoLoader'更改為'use SelfLoader'(儘管請注意,SelfLoader會導出AUTOLOAD函數 - 但如果您有自己的AUTOLOAD並且也使用AutoLoader,您可能知道您在做什麼),並將__END__標記更改為__DATA__。您需要perl版本5.001m或更高版本才能使用此功能(版本5.001及所有补丁直至补丁m)。

無需繼承自SelfLoader

SelfLoader的工作方式類似於AutoLoader,但是從__DATA__之後而不是在'lib/auto'目錄中提取子例程。不需要在安裝時運行AutoSplit模塊而帶來的維護收益,以及不需要不斷打開和關閉文件以加載子例程而帶來的運行時收益。需要解析__DATA__之後的代碼而帶來的運行時損失。您可以在該模塊的文檔中找到AutoLoader的詳細信息以及對這些區別的另一種觀點。

__DATA__,__END__和FOOBAR::DATA文件句柄。

如果要與SelfLoader一起使用FOOBAR::DATA,則此部分才相關。

模塊中__DATA__標記後的數據使用FOOBAR::DATA文件句柄進行讀取。如果在__END__後面跟隨DATA標記,則仍然可以使用__END__來表示__DATA__部分的結束 - 這由SelfLoader支持。如果找到__END__後跟隨DATA標記的__END__,則會將FOOBAR::DATA文件句柄保持打開,並將文件句柄定位到__END__標記後的行的開頭。如果不存在__END__標記,或者在同一行上找不到DATA標記的__END__標記,則會關閉文件句柄。

SelfLoaderFOOBAR::DATA文件句柄的當前位置讀取,直到EOF或__END__。這意味著如果您想使用該文件句柄(僅在您想使用時),您應該

1. 將所有子例程聲明放在__DATA__標記之後並在這些聲明之後放置自己的數據,使用__END__標記標記子例程聲明的結尾。您還必須確保SelfLoader通過調用'SelfLoader->load_stubs();'或使用自動加載的函數首先讀取。

2.您應該首先讀取FOOBAR::DATA文件處理程序,將處理程序保持打開並定位於子程序聲明的第一行。

您可能可以兩者兼而有之。

類別和繼承方法。

對於不是類別的模組,此部分不相關。只有在您擁有可能被繼承的方法時,此部分才相關。

子程序存根(或前向聲明)如下所示

sub stub;

即它是一個沒有子程序主體的子程序聲明。對於不是類別的模組,就自動加載而言,並不真正需要存根。

對於是類別的模組,並且需要處理繼承方法的模組,需要存根以確保方法繼承機制正常工作。您可以在 'require' 時將存根加載到模組中,方法是在模組中添加語句 'SelfLoader->load_stubs();' 來實現。

另一種方法是在發布模組之前在__DATA__標記之前放置存根,為此可使用Devel::SelfStubber模組。但是,這需要確保將存根放入模組中的額外步驟。如果這樣做,我強烈建議在發布模組之前這樣做 - 通常不應在安裝時進行。

多個套件和完全限定的子程序名稱

支持同一文件中的多個套件中的子程序 - 但是您應該注意,這需要將SelfLoader::AUTOLOAD導出到每個需要它的套件中。當SelfLoader首次將子程序加載到緩存中時,這將自動完成,但您應該在__DATA__之前的初始化中指定它,方法是在每個套件中放置一個 'use SelfLoader' 語句。

也支持完全限定的子程序名稱。例如,

__DATA__
sub foo::bar {23}
package baz;
sub dob {32}

__DATA__後的數據首次解析時,SelfLoader將確保正確加載所有這些,並確保套件 'foo' 和 'baz' 在擁有SelfLoader AUTOLOAD方法時是正確的。

作者

SelfLoader由perl5-porters維護。請將任何問題發送到官方郵件列表。任何適用於CPAN發布的內容都可以發送給其維護人員。

作者與維護人員:Perl5-Porters <perl5-porters@perl.org>

CPAN發行版的維護人員:Steffen Mueller <smueller@cpan.org>

版權與許可

這個套件自perl5的第一個版本發佈以來一直是perl核心的一部分。它被單獨發佈到CPAN,以便舊版安裝可以受益於錯誤修復。

這個套件與perl核心具有相同的版權和許可

版權所有 (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Larry Wall 及其他人

保留所有權利。

本程式是自由軟體;您可以依據下列條款之一重新散佈或修改:

a)

由自由軟體基金會所發布的 GNU 通用公共許可證;任何版本的第1版,或者(您可以選擇)以後的版本,或者

b)

隨附本套件的「藝術許可證」。

本程式是基於希望它將是有用的,但沒有任何保證;甚至沒有對特定用途的適用性的暗示保證。請查閱 GNU 通用公共許可證或藝術許可證以瞭解更多詳情。

您應該已經收到了一份隨附本套件的藝術許可證副本,文件名為「Artistic」。如果沒有,我將很樂意提供一份。

您還應該已經收到了一份隨附本程式的 GNU 通用公共許可證副本,文件名為「Copying」。如果沒有,請寫信給自由軟體基金會,Inc.,51 Franklin St,Fifth Floor,Boston,MA 02110-1301,USA,或者訪問他們的網頁https://gnu.dev.org.tw/copyleft/gpl.html

對於選擇使用GNU通用公共許可證的人,我對GNU通用公共許可證的理解是,除非您明確將該腳本放在GNU通用公共許可證的條款下,否則沒有Perl腳本屬於GPL的條款。此外,與perl鏈接的任何對象代碼不會自動落入GPL的條款之下,只要該對象代碼僅添加子例程和變量的定義,並且不以任何方式阻礙生成的解釋器執行任何標準Perl腳本。我認為以這種方式鏈接C子例程相當於在Perl語言本身中定義子例程。您可以將這樣的對象文件作為專有的銷售,前提是您根據GNU通用公共許可證提供或提供Perl源代碼。(這僅是指定程序的輸入的替代方式。)您還可以銷售由運行的屬於您的Perl腳本轉儲產生的二進制文件,前提是您根據GPL提供或提供Perl源代碼。(在這種情況下,Perl解釋器和您的代碼位於同一個二進制文件中,這只是一種僅僅聚集的形式。)這是我對GPL的解釋。如果您仍然有疑慮或難以理解我的意圖,請隨時與我聯繫。當然,藝術許可證為您的保護提供了所有這些信息,因此您可能更喜歡使用該許可證。