SelfLoader - 仅在需要时加载函数
package FOOBAR;
use SelfLoader;
... (initializing code)
__DATA__
sub {....
此模块告诉其用户 FOOBAR 包中的函数将从 __DATA__
标记之后自动加载。另请参见 "perlsub 中的自动加载".
__DATA__
标记告诉 perl 编译器 perl 代码的编译已完成。__DATA__
标记之后的所有内容都可通过文件句柄 FOOBAR::DATA 读取,其中 FOOBAR 是到达 __DATA__
标记时当前包的名称。这与包 'main' 中的 __END__
工作方式相同,但对于其他模块,__END__
之后的数据不会自动检索,而 __DATA__
之后的数据则会。在 5.001m 之前的 perl 版本中,__DATA__
标记不被识别。
请注意,同一个包中的多个文件中可能存在__DATA__
标记,编译器遇到的最后一个__DATA__
标记是文件句柄可以访问的标记。这也适用于__END__
和main,即如果“main”程序有__END__
,但该程序“require”(_不是_“use”)的模块有一个“package main;”声明,后面跟着一个“__DATA__
”,那么DATA
文件句柄将被设置为访问模块中__DATA__
之后的数据,_而不是_“main”程序中__END__
标记之后的数据,因为编译器在后面遇到“require”的文件。
SelfLoader的工作原理是用户将__DATA__
标记放在需要在“require”时编译和运行的perl代码_之后_,但在可以稍后加载的子程序声明_之前_ - 通常是因为它们可能永远不会被调用。
SelfLoader将从FOOBAR::DATA文件句柄读取,以加载__DATA__
之后的数据,并在调用任何子程序时加载它。成本是一次解析__DATA__
之后的数据,以及任何自动加载函数的_第一次_调用的加载延迟。好处(希望如此)是编译阶段加快,无需加载从未使用过的函数。
如果遇到__END__
标记,SelfLoader将停止从__DATA__
读取 - 正如您所期望的那样。如果存在__END__
标记,并且后面跟着标记DATA,那么SelfLoader将在该标记之后的行上保持FOOBAR::DATA文件句柄打开。
SelfLoader将AUTOLOAD
子程序导出到使用SelfLoader的包中,并在第一次调用时加载该子程序。
将_总是_被调用的子程序放在__DATA__
标记之后没有任何优势。
一个“my $pack_lexical”语句使变量$pack_lexical仅对文件到__DATA__
标记为止局部。在其他地方声明的子程序_无法_看到这些类型的变量,就像您在包中但在另一个文件中声明子程序一样,它们无法看到这些变量。
因此,具体来说,自动加载的函数无法看到包局部变量(这适用于SelfLoader和Autoloader)。vars
pragma 提供了一种替代方法来定义包级全局变量,这些全局变量将对自动加载的例程可见。有关vars的文档,请参阅perlmod中关于pragma部分的内容。
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的详细信息以及这些区别的另一种观点,请参阅该模块的文档。
本节仅与您希望将FOOBAR::DATA
与SelfLoader一起使用的情况相关。
模块中__DATA__
标记之后的数据使用FOOBAR::DATA文件句柄读取。如果__DATA__
部分之后紧跟DATA标记,则仍然可以使用__END__
来表示__DATA__
部分的结束 - SelfLoader支持此功能。如果找到__END__
之后紧跟DATA,则FOOBAR::DATA文件句柄保持打开状态,文件句柄定位在__END__
标记之后行的开头。如果没有__END__
标记,或者__END__
标记与同一行上的DATA标记不匹配,则文件句柄将关闭。
SelfLoader从FOOBAR::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}
都将由 SelfLoader 正确加载,并且 SelfLoader 将确保当 __DATA__
之后的数据首次解析时,包 'foo' 和 'baz' 正确地拥有 SelfLoader AUTOLOAD
方法。
SelfLoader
由 perl5-porters 维护。请将任何问题发送到规范的邮件列表。不过,任何适用于 CPAN 版本的内容都可以发送给它的维护者。
作者和维护者:The Perl5-Porters <[email protected]>
CPAN 版本的维护者:Steffen Mueller <[email protected]>
此包自 perl5 的第一个版本发布以来就一直是 perl 核心的一部分。它已单独发布到 CPAN,以便旧版本可以从错误修复中受益。
此包与 perl 核心具有相同的版权和许可
版权所有 (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 by Larry Wall 和其他人
保留所有权利。
此程序是免费软件;您可以在自由软件基金会发布的 GNU 通用公共许可证的条款下重新发布和/或修改它;版本 1 或(由您选择)任何更高版本,或
此程序按“现状”提供,不提供任何形式的明示或暗示保证,包括但不限于适销性或特定用途适用性的暗示保证。有关更多详细信息,请参阅 GNU 通用公共许可证或 Artistic 许可证。
您应该已经收到此工具包的 Artistic 许可证副本,该副本位于名为“Artistic”的文件中。如果没有,我很乐意提供一个。
您还应该已经收到此程序的 GNU 通用公共许可证副本,该副本位于名为“Copying”的文件中。如果没有,请写信给自由软件基金会,Inc.,51 Franklin St,Fifth Floor,Boston,MA 02110-1301,USA 或访问他们在互联网上的网页 http://www.gnu.org/copyleft/gpl.html。
对于那些选择使用 GNU 通用公共许可证的人来说,我对 GNU 通用公共许可证的解释是,除非您明确地将 Perl 脚本置于 GPL 的条款下,否则任何 Perl 脚本都不属于 GPL 的条款。此外,与 perl 链接的任何目标代码不会自动属于 GPL 的条款,前提是此类目标代码仅添加子例程和变量的定义,并且不会以其他方式妨碍生成的解释器执行任何标准 Perl 脚本。我认为以这种方式链接 C 子例程等同于在 Perl 语言本身中定义子例程。您可以将此类目标文件作为专有文件出售,前提是您提供或提供 Perl 源代码,如 GNU 通用公共许可证所指定。(这仅仅是指定程序输入的另一种方式。)您也可以出售由您拥有的正在运行的 Perl 脚本转储产生的二进制文件,前提是您提供或提供 Perl 源代码,如 GPL 所指定。(在这种情况下,Perl 解释器和您的代码位于同一个二进制文件中的事实仅仅是聚合的形式。)这是我对 GPL 的解释。如果您仍然有任何疑虑或难以理解我的意图,请随时与我联系。当然,Artistic 许可证为您的保护明确说明了所有这些内容,因此您可能更愿意使用它。