管理由多个文件组成的模块中导入的模块

时间:2017-07-27 15:57:59

标签: perl module

我正在构建我的第一个Perl模块,我想知道在您自己的模块中加载模块的最佳做法是什么。我确实阅读了this answer,但它似乎谈到了单个文件项目。

我开始只是在主文件中加载项目中我需要的所有模块(让我们称之为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中的 MyModule.pm File :: Path,但仅限于MyMethod.pm

此外,是否应该将其扩展到子例程的特定use个?例如,假设我需要在MyModule.pm和MyMethod.pm中使用catdir,但在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风格'是什么,或者是否有任何这些例子的上升/下降。

1 个答案:

答案 0 :(得分:0)

我认为一个好的一般原则是be specific我将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);

此双use中没有暗示效率低下。为了解释原因,我们需要检查它的工作原理。

use Module qw/ foo bar baz /;

大致相当于:

require Module;
Module->import( qw/ foo bar baz / );

require加载并编译模块当且仅当之前加载时(为此,它会检查特殊哈希的状态{ {1}}:您可以在documentation for require

中阅读更多详情

%INC将被调用三次(import中的一个,MyModule中的一个和MyMethod中的一个),但由于单向或某种方式,它无法绕过它其他我们需要在每个包中都有这些符号。

仅导入所需内容也是记录模块/意图/的一种形式,它也可以使视角更容易进行重构。