我是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说的,但我想得到一些关于此的意见)。
答案 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'。