【问题标题】:Old .pl modules versus new .pm modules旧 .pl 模块与新 .pm 模块
【发布时间】:2010-09-17 09:04:15
【问题描述】:

我是 Perl 的初学者,我正在尝试在脑海中构建构建 Perl 程序的最佳方法。我精通Python,习惯了pythonfrom foo import bar从python模块中导入函数和类的方式。正如我在 Perl 中所理解的那样,有很多方法可以做到这一点,.pm 和 .pl 模块、EXPORT 和 @ISA、use 和 require 等,初学者很难清楚地了解哪些区别,各有优缺点(即使在阅读了初级 Perl 和中级 Perl 之后)。

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

Perl 模块文件具有 扩展名.pm。 use 运算符 假设这一点,所以你不必 用引号拼出“Module.pm”。这 也有助于区分新的 来自旧 .pl 和 .ph 文件的模块。

old.pl 准备模块的方式和 new.pm 方式有什么区别?

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

【问题讨论】:

  • @Zaid:不,您链接到的问题询问纯脚本和模块之间的区别是什么/为什么。这是关于旧式require-ed 和新式use-ed 模块之间区别的问题。
  • @Dummy,是的,正确。在写我的之前,我已经知道了另一个 SO 问题。 @Everybody:感谢您的宝贵时间,非常有帮助。很遗憾,我只能选择一个问题作为最佳问题。
  • @Zaid:看起来你现在有足够的声望来提交近距离投票——既然你评论说这是一个骗局,你应该提交这样的投票。 :)

标签: perl perl-module


【解决方案1】:

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

【讨论】:

  • 具体来说,Perl 5 的 Sweet Sixteen 将于 2010 年 10 月 17 日发布。 (Perl 本身将在 12 月 23 岁。)
【解决方案2】:

旧的 .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 中也有很好的描述)。

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 所以你是在暗示 5.12.2 团队不是“p to date with Perl development” :-) 说真的,这是相当旧的信息。任何刚接触 Perl4 的人现在都可能转换到 Perl 5。
    【解决方案4】:

    我对 .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();
    

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

    使用会加载您的模块并调用 import,这将使任何 EXPORTed subs 在您当前的包中可用。在第二个例子中,一个 require 会做,它不会调用 import,但我倾向于总是使用 'use'。

    【讨论】:

    • 如果不加载 Exporter,您的第一个版本的 MyPkg 将无法正常工作。
    • “非 OO”模块通常使用 ISA 通过 Exporter 定义导入例程。错误地引用奥威尔的话,“所有模块都是面向对象的,有些模块比其他模块更面向对象”。
    • justintime:这也是“老办法”。现代是“使用Exporter'import';”。它从 5.8.3 开始可用,它也很旧,甚至可以在带有 Exporter 的旧 Perls 上使用,请从 CPAN 升级。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 2016-05-05
    • 1970-01-01
    • 2011-03-25
    • 2021-07-24
    相关资源
    最近更新 更多