关于“未定义子例程”的Perl模块错误

时间:2012-04-25 14:59:26

标签: perl module cygwin

我正在尝试使用名为Math::Counting的模块:

#!/usr/bin/perl 

use strict;
use warnings;
use Math::Counting;

my $f = factorial(3);
print "$f\n";

但是当我运行它时,我收到以下错误

$ perl UsingModules.pl
Undefined subroutine &main::factorial called at UsingModules.pl line 8.

似乎函数factorial没有被导出,但为什么?

当我使用以下

my $f = Math::Counting::factorial(3);

而不是上面的内容,它完全正常,但我很好奇为什么函数无法导出。

我在Cygwin上使用perl v5.10.1。

6 个答案:

答案 0 :(得分:7)

Math::Counting看起来有点傻(我的意思是学生工程模式?)模块提供的真实阶乘功能,bfactMath::BigInt::bfac周围的薄包装。所以,只需使用Math::BigInt

#!/usr/bin/env perl

use strict; use warnings;
use Math::BigInt();

print Math::BigInt->bfac('300'), "\n";

输出:

30605751221644063603537046129726862938858880417357699941677674125947653317671686
74655152914224775733499391478887017263688642639077590031542268429279069745598412
25476930271954604008012215776252176854255965356903506788725264321896264299365204
57644883038890975394348962543605322598077652127082243763944912012867867536830571
22936819436499564604981664502277165001851765464693401122260347297240663332585835
06870150169794168850353752137554910289126407157154830282284937952636580145235233
15693648223343679925459409527682060806223281238738388081704960000000000000000000
0000000000000000000000000000000000000000000000000000000

I did not verify the result

正如其他人所说,Math::Counting有:

our @ISA = qw(Exporter);
our @EXPORT = qw(
    factorial permutation combination
    bfact     bperm       bcomb
);

但没有require Exporter

实际上,此模块不需要从Exporter 继承。一个简单的:

use Exporter 'import'; 

就足够了。此外,默认情况下确实不需要污染此模块用户的命名空间,因此它应该具有:

our @EXPORT = ();
our @EXPORT_OK = qw(
    factorial permutation combination
    bfact     bperm       bcomb
);

否则,定义%EXPORT_TAGS的重点是什么?

答案 1 :(得分:7)

模块中有一个错误。 Math::Counting ISA Exporter,但Math::Counting未加载Exporter

解决方法:您可以手动requireuse Exporter

更好:向模块作者提交错误,提供测试用例。

注释:

哦,非常有趣。模块作者确实测试了他的函数,但是Test::More引入了Exporter,这意味着没有注意到模块源的遗漏。

更新

Math::Counting 0.0904已经发布,解决了这个问题。

答案 2 :(得分:2)

似乎Math::Counting缺少require Exporter;,因此没有任何函数被导出到您的命名空间。

答案 3 :(得分:2)

在一位向CPAN提交有关我遗忘的需求声明的错误报告的好人提醒之后,我修复了模块导出,包括关于“污染命名空间”的评论。

另外,我在文档中添加了一个注释,它是Math::BigInt->bfac()用于真实世界应用程序的“瘦包装”。当我做它时,我找不到排列或组合的简单计算。现在有太多......

答案 4 :(得分:0)

使用use Math::Counting调用时,Math :: Counting模块似乎没有导出阶乘方法。

CPAN页面执行以下操作

use Math::Counting ':student';

然后将factorial方法导出到您的命名空间中,您可以在不预先添加整个包名的情况下使用它。

答案 5 :(得分:0)

查看Math :: Counting的源代码,看看它是什么版本。您可以通过以下方式找到源所在的位置:

prompt> perldoc -l Math::Counting

通过查看模块的$VERSION变量,您还可以在90%的时间内找到模块的版本:

use Math::Dumper;
print "The version of Math::Dumper is $Math::Dumper::VERSION\n";

我刚下载了版本0.0902,以下程序运行正常:

#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);

use Math::Counting;

say $Math::Counting::VERSION;
say factorial(6);

我注意到在这个版本中,他有:

our @ISA = qw(Exporter);
our @EXPORT = qw(
    factorial permutation combination
    bfact     bperm       bcomb
);

因此,看起来作者会自动导出此特定版本中的所有子例程。作者还有两组定义的导出标记:studentbig

可能是在早期版本中,他没有定义@EXPORT,但使用@EXPORT_OK(这是更好的),你必须这样做:

use Match::Counting qw(:student);

use Math::Counting qw(factorial);