我正在构建我的第一个 Perl 模块,我想知道在您自己的模块中加载模块的最佳实践是什么。我确实阅读了这个答案,但它似乎在谈论单个文件项目。
我开始时只是在主文件中加载我在项目中需要的所有模块(我们称之为MyModule.pm
),如下所示:
use Config::IniFiles;
use File::Spec qw(catdir catfile curdir);
use File::Path qw(remove_tree);
use File::Basename qw(fileparse dirname);
use Cwd qw(abs_path);
use XML::Twig;
use Getopt::Long;
但后来我意识到并非所有模块(或子程序/方法)都是必需的。例如,可能File::Path
仅在模块的单个方法中需要它,该模块具有自己的文件(例如MyMethod.pm
)。那么我会不会在 use
File::Path 中MyModule.pm
,而只是在MyMethod.pm
此外,这是否也应该扩展到特定use
的子程序?例如,假设我需要catdir
在 MyModule.pm 和 MyMethod.pm 中使用,但是在 AnotherMethod.pm 中使用 catfile,我是否也将其拆分?我假设 Perl 会忽略已经导入的子例程,但我问的是常见的做法。我会这样做吗?
# MyModule.pm
use File::Spec qw(catdir);
...
# MyMethod.pm
use File::Spec qw(catdir);
...
# AnotherMethod.pm
use File::Spec qw(catfile);
...
更确切地说
# MyModule.pm
use File::Spec qw(catdir catfile);
...
# MyMethod.pm
use File::Spec qw(catdir catfile);
...
# AnotherMethod.pm
use File::Spec qw(catdir catfile);
...
甚至干脆
# MyModule.pm
use File::Spec qw(catdir catfile);
...
对我来说,将它们分开似乎很好,就像第一个例子一样。这样,您可以立即看到每个文件的依赖项是什么。但我想知道典型的“Perl 风格”是什么,或者这些示例中是否有任何优点/缺点。
我认为一个好的一般原则是具体(我将 Peter Norvig 和 Kent Pitman 的幻灯片链接到他们关于 Lisp 编程良好风格的教程:有特定于 Lisp 的部分,但也有很好的一般建议)。
这意味着在多文件项目中,每个模块都应该在需要的最窄范围(我的意思是文件范围)中使用。在顶层包中加载模块会违反这个特殊性原则,因为它们在那里不是特别需要的。
话虽如此,我认为我们可以将此标准扩展到将符号导入命名空间。我的意思是你的例子中的这种风格:
# MyModule.pm use File::Spec qw(catdir); ... # MyMethod.pm use File::Spec qw(catdir); ... # AnotherMethod.pm use File::Spec qw(catfile);
这个 double 没有暗示低效率use
。为了解释原因,我们需要检查它如何工作的一些细节。
use Module qw/ foo bar baz /;
大致相当于:
require Module;
Module->import( qw/ foo bar baz / );
require
加载和编译的模块当且仅当它已经不加载之前(这样做,它会检查特殊哈希的状态%INC
:你可以阅读更详细的文档require
。
import
将被调用三次(一个 in MyModule
,一个 inMyMethod
和一个 in AnotherMethod
),但是没有办法绕过它,因为我们需要以一种或另一种方式在每个包中包含这些符号。
仅导入需要的内容也是记录模块 /intentions/ 的一种形式,并且从角度来看,它还可以使重构更容易。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句