4

I'm a beginner in Perl and I'm trying to build in my head the best ways of structuring a Perl program. I'm proficient in Python and I'm used to the python from foo import bar way of importing functions and classes from python modules. As I understood in Perl there are many ways of doing this, .pm and .pl modules, EXPORTs and @ISAs, use and require, etc. and it is not easy for a beginner to get a clear idea of which are the differences, advantages and drawbacks of each (even after reading Beginning Perl and Intermediate Perl).

The problem stated, my current question is related to a sentence from perldoc perlmod:

Perl module files have the extension .pm. The use operator assumes this so you don't have to spell out "Module.pm" in quotes. This also helps to differentiate new modules from old .pl and .ph files.

Which are the differences between old .pl way of preparing modules and the new .pm way?

Are they really the old and the modern way? (I assume they are because Perlmod says that but I would like to get some input about this).

4

4 回答 4

9

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

于 2010-09-17T09:32:02.553 回答
4

准备模块的旧 .pl 方式和新的 .pm 方式有哪些区别?

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

在过去,没有包裹。一个是在做例如require "open2.pl";,这类似于本质上包括文件的内容,因为它是在调用脚本中。所有声明的函数,所有全局变量都成为脚本上下文的一部分。或者换句话说:污染你的上下文。包含多个文件可能会导致所有可能的冲突。

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

@EXPORT/@EXPORT_OK列表由标准实用程序模块使用,Exporter它有助于将模块函数导入调用上下文:因此不必一直编写函数的全名。列表通常由模块根据传递给use类似的参数列表进行自定义use POSIX qw/:errno_h/;。有关perldoc Exporter更多详细信息,请参阅。

@ISA是 Perl 的继承机制。它告诉 Perl 如果在当前包中找不到函数,则在@ISA. 简单的模块通常只有Exporter提到的使用它的import()方法(在同一个中也有很好的描述perldoc Exporter)。

于 2010-09-17T09:52:49.803 回答
3

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

这是一种令人讨厌的古老做事方式。如果您遇到推荐它的文档,那么这强烈表明您应该忽略该文档,因为它要么真的很旧,要么是由十五年没有跟上 Perl 开发的人编写的。

有关以现代方式构建 Perl 模块的不同方法的一些示例,请参阅我对 Perl 模块方法调用的回答:无法在 ${SOMEFILE} 行 ${SOMELINE} 的未定义值上调用方法“X”

于 2010-09-17T09:32:31.180 回答
1

我对 .pl 而不是模块一无所知,而不是它们在一段时间前确实存在,现在似乎没有人使用它们,所以你可能也不应该使用它们。

坚持使用 pm 模块,现在忽略 @ISA,这是面向 OOP 的。导出也不是那么重要,因为您始终可以调用您的方法完全合格。

所以不要写这个:

文件:MyPkg.pm

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

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

文件:main.pl

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

use MyPkg;

&func1();

首先,您应该这样写:

文件:MyPkg.pm

package MyPkg;

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

文件:main.pl

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

use MyPkg;

&MyPkg::func1();

稍后,当您看到应该真正导出哪些方法时,您可以这样做,而无需更改现有代码。

使用加载您的模块并调用导入,这将使您当前包中的任何 EXPORTed 潜艇可用。在第二个示例中,需要执行此操作,它不会调用导入,但我倾向于始终使用“使用”。

于 2010-09-17T09:21:52.527 回答