1

我每隔一段时间就会遇到这个问题。出于某种原因,我在尝试调用导出的子程序时收到“未定义的子程序”错误,我不知道为什么,因为它似乎是在成熟的代码中突然发生的。

上次发生这种情况时,我想我使用了“package_2::exported_sub()”之类的东西。这一次有效,但它只是为 package_2 中的另一个子返回了一个错误。甚至把“使用package_2;” 在上面的行没有帮助!我唯一能想到的是,导出的 sub 以某种方式未定义。

我的代码看起来有点像这样:

在文件 package_1.pm 中:

package package_1;

require Exporter;
@ISA = qw( Exporter );

@EXPORT = qw(
local_sub
);

use package_2;
use strict;
use warnings;
use diagnostics;

sub local_sub {
  &exported_sub;
}

在文件 package_2.pm 中:

package package_2;

require Exporter;
@ISA = qw( Exporter );

@EXPORT = qw(
exported_sub
);

use strict;
use warnings;
use diagnostics;

sub exported_sub {
 # do something
}

我已经束手无策了......当这个弹出来时,我正在处理一张不相关的热门票,明天开始用户测试!

提前致谢!


更新:

ikegami,感谢您的修复!不过我很好奇。我又遇到了这个问题,但这一次我没有找到循环依赖。我把它缩小到一行:

$row->{$attr} = ' ' unless ( $row->{$attr} );

显然,该行与使用或要求根本无关!我查看了 Apache 日志,但似乎没有什么特别突出的,但会努力解决我发现的任何问题。我也会看看我是否可以获得更多警告。

除此之外,您建议下一步做什么?

谢谢!

4

3 回答 3

4

我怀疑你有一个循环依赖: package_1 使用 package_2 而 package_2 使用 package1 (直接或间接)。

以下是我最初在 PerlMonks 上发布的解决方案:http ://www.perlmonks.org/?node_id=778639


[ 使用这种技术的需要是系统中设计缺陷的一个非常强烈的指标,但我认识到资源并不总是可用于修复设计缺陷。]

如果ModA使用ModB,ModB使用ModA,ModA或ModB从对方导入符号,需要注意代码执行顺序。我发现避免问题的最佳方法是在加载任何其他模块之前设置 Exporter。

ModA.pm

package ModA;

use strict;
use warnings;

BEGIN {
   our @ISA = qw( Exporter );
   our @EXPORT_OK = qw( ... );
   require Exporter;
}

use This;
use ModB;
use That;

...

1;

ModB.pm

package ModB;

use strict;
use warnings;

BEGIN {
   our @ISA = qw( Exporter );
   our @EXPORT_OK = qw( ... );
   require Exporter;
}

use This;
use ModA;
use That;

...

1;
于 2012-08-30T19:10:30.780 回答
1

你确定你的use线完全一样,而不是类似的东西use package_2 qw(xyz);吗?

后者将定义 Exporter 的 import() 子例程将导出到调用者模块中的内容。

于 2012-08-30T17:48:08.180 回答
0

我希望我的经验能适合你的情况。Perl 包名必须用 Namespace 填写。如果你的模块文件在路径 $PERL_LIB/Fruit/Apple.pm 那么在模块文件中,你必须指定命名空间 Fruit::

package Fruit::Apple;

.......

如果你只写

package Apple;

.......

没有编译错误。但是当你在模块文件 Apple.pm 中调用你的方法时,会得到“未定义的子程序”错误。

于 2016-08-08T11:38:06.147 回答