在Perl中,使用模块比需要文件更好吗?
另一个问题让我想到了不同的代码重用方法: use
vs. require
vs. do
我在这里看到很多post,其中的问题围绕使用require
来加载和执行代码。 这在我看来似乎是一个明显不好的做法,但在这个问题上,我没有find任何可以指向人的好资源。
perlfaq8涵盖了use
和require
之间的区别,但是它并没有提供任何有关偏好的build议(截至5.10 – 在5.8.8中有一些赞成使用的build议 )。
这个话题似乎缺乏讨论。 我有几个问题想要查看:
- Perl中的代码重用的首选方法是什么?
-
use ModuleName;
-
require ModuleName;
-
require 'file.pl';
-
do 'file.pl';
-
-
require ModuleName
和require "file.pl"
之间有什么区别? - 是否使用
require "file.pl"
是一个好主意? 为什么或者为什么不?
标准的做法是大部分时间使用,偶尔require
,而且很less使用。
do 'file'
将执行file
作为Perl脚本。 这几乎就像在文件的内容上调用eval
一样; 如果你多次do
相同的文件(例如在一个循环中),它将被parsing和评估每一次,这是不可能是你想要的。 do
和eval
之间的区别是在封闭范围内不能看到词法variables,这使得它更安全。 对于像处理以Perl代码forms编写的configuration文件这样的简单任务偶尔有用。
require 'file'
就像do 'file'
,只是它将只parsing任何特定的文件一次,并会引发exception,如果出现问题。 (例如,文件找不到,包含语法错误等)。自动错误检查使它成为do 'file'
一个很好的替代品,但它仍然只适用于相同的简单用途。
do 'file'
和require 'file'
格式是* .pl文件扩展名表示“Perl库”之后几天来的结转。 在Perl中重用代码的现代方式是将其组织成模块。 调用某个“模块”而不是“库”只是语义上的,但这些词在Perl文化中意味着截然不同的东西。 一个库只是一个子程序的集合。 一个模块提供了一个名称空间,使其更适合于重用。
use Module
是从模块使用代码的正常方式。 请注意, Module
是包名称,不是包含文件名的带引号的string。 Perl为你处理从包名到文件名的转换。 use
语句在编译时发生,如果失败则抛出exception。 这意味着如果你的代码依赖的模块不可用或者加载错误将会立即显现。 此外,如果use
模块的import()
方法, use
自动调用import()
方法,这样可以节省一些打字的时间。
require Module
就像use Module
除了它发生在运行时,并不会自动调用模块的import()
方法。 通常情况下,你想使用use
失败及可预见的,但有时require
更好。 例如,可以使用require
来延迟仅偶尔需要的大模块的加载或使模块可选。 (例如,如果可用,则使用该模块,但是如果不是则可以使用其他function,或者减lessfunction。)
严格地说, require Module
和require 'file'
之间的唯一区别就是第一个表单触发了从Foo::Bar
这样的包名到像Foo/Bar.pm
这样的文件名的自动翻译,而后一个表单需要一个文件名从…开始。 按照惯例,第一种forms用于加载模块,而第二种forms用于加载库。
使用use
有一个主要优先select,因为它在编译期间发生在更早的状态BEGIN {}
,错误往往会在更适当的时间传播给用户。 它还调用了sub import {}
函数,它使调用者能够控制导入过程。 这是大量使用的东西。 你可以通过调用特定的命名空间的import
来获得相同的效果,但是这要求你知道命名空间的名称和文件,并将调用编码到子例程中,这是更多的工作。 相反, use
,只是要求你知道命名空间,然后它需要具有匹配的命名空间的文件 – 从而使得名称空间和文件之间的链接对用户意识不大。
阅读perldoc -f use
, perldoc -f require
更多的信息。 每perldoc -f use
:
use
与BEGIN { require Module; Module->import( LIST ); }
BEGIN { require Module; Module->import( LIST ); }
BEGIN { require Module; Module->import( LIST ); }
这更丑陋了。
主要区别在于导入/导出。 当你使用一个模块时,最好使用它,因为它允许你指定你想要导入到你的名字空间的例程:
use MyModule qw(foo bar baz); # allows foo(), bar() and baz() to be used use MyModule qw(); # Requires explicit naming (eg MyModule::foo).
use
也给运行模块的import()
程序,这个程序经常用来设置模块。
请参阅perldoc以获取更多细节。
使用模块将在编译期间包含模块,这会增加速度但使用更多内存,而使用require
模块将在运行时包含。 需要一个模块,而不需要导入时使用较less的内存,但降低速度。