旧的.pl模块与新的.pm模块

时间:2010-09-17 09:04:16

标签: perl perl-module

我是Perl的初学者,我正在努力构建构建Perl程序的最佳方法。我精通Python,我习惯于从python模块导入函数和类的python from foo import bar方式。正如我在Perl中所理解的那样,有很多方法可以做到这一点,.pm和.pl模块,EXPORT和@ISAs,使用和要求等等。初学者不容易弄清楚哪些是差异,每个的优点和缺点(甚至在阅读Beginning Perl和Intermediate Perl之后)。

问题所在,我目前的问题与perldoc perlmod的一句话有关:

  

Perl模块文件有   扩展名.pm。 use运算符   假定这是你不必的   在引号中拼出“Module.pm”。这个   也有助于区分新的   来自旧.pl和.ph文件的模块。

.pl准备模块的方式和 new .pm方式之间的区别是什么?

他们真的是现代方式吗? (我认为它们是因为Perlmod说的,但我想得到一些关于此的意见)。

4 个答案:

答案 0 :(得分:8)

use函数和.pm类型模块是在下个月16年前发布的Perl 5中引入的。 Perlmod所指的“旧.pl和.ph文件”与Perl 4(及更早版本)一起使用。在这一点上,他们只对计算机历史学家感兴趣。出于您的目的,只需忘记.pl库。

答案 1 :(得分:4)

  

旧的.pl准备模块的方式与新的.pm方式有什么不同?

你可以在Perl自己的标准库中找到几个旧模块(由@INC指向,路径可以在perl -V输出中看到。)

在较旧的时代,没有包裹。一个人在做,例如require "open2.pl";类似于基本上包含调用脚本中的文件内容。声明了所有函数,所有全局变量都成为脚本上下文的一部分。或者换言之:污染您的上下文。包含多个文件可能会导致所有可能的冲突。

新模块使用package关键字来定义自己的上下文和命名空间的名称。当脚本use时,新模块有可能不向脚本的直接上下文导入/添加任何内容,从而防止命名空间污染和潜在的冲突。

@EXPORT / @EXPORT_OK列表由标准实用程序模块Exporter使用,它有助于将模块函数导入调用上下文:这样一个人不必一直写入功能的全名。列表通常由模块自定义,具体取决于use中传递给use POSIX qw/:errno_h/;的参数列表。有关详细信息,请参阅perldoc Exporter

@ISA是Perl的继承机制。它告诉Perl如果它无法在当前包中找到一个函数,那么要扫描@ISA中提到的所有包中的函数。简单模块通常只有Exporter提到使用其import()方法(同样的perldoc Exporter中也有详细描述)。

答案 2 :(得分:3)

通过创建.pl文件重用代码(“pl”实际上代表“Perl库”)是在Perl 4中完成的方式 - 在我们使用'package'关键字和'use'语句之前。

这是一种令人讨厌的旧方式。如果您遇到推荐它的文档,那么这是一个强烈的迹象,表明您应该忽略该文档,因为它要么真的很旧,要么是由一个没有及时了解Perl开发超过15年的人写的。

有关以现代方式构建Perl模块的不同方法的一些示例,请参阅my answer to Perl Module Method Calls: Can't call method “X” on an undefined value at ${SOMEFILE} line ${SOMELINE}

答案 3 :(得分:1)

我不知道.pl而不是模块,而不是它们确实存在,现在似乎没有人使用它们,所以你也不应该使用它们。

坚持下午模块,现在忽略@ISA,那是OOP。导出也不是那么重要,因为你总是可以完全调用你的方法。

所以不要写这个:

文件:MyPkg.pm

package MyPkg;
@EXPORT = qw(func1 func2);

sub func1 { ... };
sub func2 { ... };

file:main.pl

#!/usr/bin/perl
use strict;
use warnings;

use MyPkg;

&func1();
你应该在开始时写下:

文件:MyPkg.pm

package MyPkg;

sub func1 { ... };
sub func2 { ... };

file:main.pl

#!/usr/bin/perl
use strict;
use warnings;

use MyPkg;

&MyPkg::func1();

稍后当您看到应该真正导出哪些方法时,您可以在不必更改现有代码的情况下执行此操作。

使用会侵占您的模块并调用导入,这将使您当前包中的任何EXPORTed潜艇都可用。在秒示例中,require会执行,但不会调用import,但我倾向于始终使用'use'。