【问题标题】:Why can't I call my exported subroutine in my Perl program?为什么我不能在我的 Perl 程序中调用我导出的子例程?
【发布时间】:2010-09-15 15:18:59
【问题描述】:

我是 Perl 的新手,我遇到了以下问题,不知道为什么以下不工作。

我的 Perl 模块包含:

package PACK2;
use Exporter;
@ISA = ('Exporter');
@EXPORT_OK=('whom');

sub why(){
    print "why\n";
}

sub whom(){
      print "whom\n";
}
1;

我的 Perl 文件包含:

#!/usr/bin/perl -w

use pack;
use pack2 ('whom');

PACK::who();
&whom();

我运行这个程序,找不到whom

perl use_pack_pm.pl

who
Undefined subroutine &main::whom called at use_pack_pm.pl line 7.

【问题讨论】:

  • 我不确定,所以我不会将此作为答案发布,但我相信这里可能会区分大小写。 (你称你的包为“PACK2”,但使用“pack2”,文件名为“pack2.pm”。我认为所有这些都需要相同!)
  • USUW -> use strict; use warnings;!!如果您有一个为什么没有发生的问题——请使用该语言提供的工具。如果你需要print "$@\n$!\n";如果你没有充分理解警告use diagnostics;
  • @Joe:请记得标记答案。

标签: perl module exporter


【解决方案1】:

Perl 是一种区分大小写的语言。我不认为模块“pack2”和“PACK2”是一样的。 (但我还没有实际测试过。)

【讨论】:

  • 是的,在将文件名更改为 PACK2.pm 后,您的操作是正确的。在那种情况下,perl 在两种不同的情况下表现出两种不同的方式。在我上面的例子中使用包;第一个模块工作正常。这是第一个模块中包含的内容..........................> cat pack.pm package PACK;子为什么(){打印“为什么\ n”; } sub who(){ 打印 "谁\n"; } 1
  • 你是对的。它们是完全不同的包。因此,Perl 加载 pack2.pm,而不是use PACK2 包。可能,使用警告会告诉你这一点。
  • 有时保留大小写但不区分大小写的文件系统可以让人们摆脱这些大小写问题。
  • 另请注意,并非所有 shell 都支持 shebang 行上的选项。这就是为什么最好写使用警告而不是附加 -w 那里。
  • @reinierpost,perl 将始终尝试读取 #! 上的开关!即使 shell 没有执行文件的行。出于其他原因,use warnings; 仍然更可取,例如在期望在没有警告的情况下运行的代码中不启用警告,或者因为在不使用 -w 的脚本中使用了模块而丢失警告。
【解决方案2】:

在内部 use pack2 ('whom'); 被翻译成类似的东西

BEGIN {
    require pack2;
    pack2->import('whom');
}

除了 perl 会在尝试调用它之前检查它是否可以在 pack2 上调用 import。 在您的示例中,没有名为 pack2 的包,因此没有要调用的 import 函数。 如果你的包名和文件名匹配,那么 perl 会找到 Exporter 提供的 import 函数。

对此没有任何警告,因为 Perl 很难判断这是何时故意进行的。 大多数 OO 模块不会导出任何函数或变量,因此它们不会提供 import 函数。

【讨论】:

  • 谢谢它回答我的问题。
  • 我很遗憾地说我只能给一个+1。我已经解释过很多次了,文件名和包名不必匹配,一个文件可以包含多个包,一个包可以分布在多个文件中等等,但从来没有注意到use和Exporter只能一起工作如果文件名和包名匹配,则正确。
  • @Ven'Tatsu:如果我对你和 Dave 的理解正确,那么从与文件名不同的包中导入函数的正确方法是什么?
  • @vol7ron,我认为虽然有一些方法可以从与其文件名不匹配的包中导入,但我认为没有一个是正确的。有时功能胜过正确 =) 在这些情况下我会使用 BEGIN { require 'File.pm'; Package->import('function'); } 假设 File.pm 是文件名,Package 是该文件中的包。我会使用 require 的文件名样式来更清楚地表明我没有加载“正确的”Perl 模块。但所有这一切都会在弄清楚我为什么不能mv File.pm Package.pm之后来。
  • @Ven'Tatsu:从my recent post here 可以看出,我并不经常使用 Exporter。我开始提出的问题是,如果您有一个包含多个包的模块,那么如何加载其他包?
【解决方案3】:

在未在包中声明完整路径的情况下使用子文件夹树中的模块时遇到相同的错误。

你应该用它的路径编写包语句。 对于位于子目录Dir 中的模块,请写入package Dir::Module;,而不是package Module ;。然后就可以了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    • 2023-03-05
    • 2014-05-24
    相关资源
    最近更新 更多