6

我正在尝试使用一个名为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);

而不是上面的,它工作得很好,但我很好奇为什么不能导出这个函数。

perl在 Cygwin 上使用 v5.10.1。

4

6 回答 6

7

Math::Counting看起来有点傻(我的意思是学生模式与工程模式?)模块提供的真正的bfact阶乘函数是对Math::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
000000000000000000000000000000000000000000000000000000000

我没有验证结果

正如其他人所指出的,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何在?

于 2012-04-25T15:13:22.530 回答
7

模块中存在错误。Math::Counting ISA Exporter,但Math::Counting不加载Exporter

解决方法:您可以要求或手动使用。 Exporter

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

评论:

哦,很有趣。模块作者确实测试了他的功能,但是Test::More拉入了Exporter,这意味着模块源代码中的这个遗漏没有被注意到。

更新:

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

于 2012-04-25T15:29:03.820 回答
2

似乎Math::Counting丢失了require Exporter;,因此没有一个函数被导出到您的命名空间。

于 2012-04-25T15:26:33.110 回答
2

在收到一个好心人向 CPAN 提交了关于我忘记的 require 语句的错误报告后,我修复了模块导出,包括关于“污染命名空间”的评论。

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

于 2012-04-26T15:45:33.300 回答
0

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

CPAN 页面执行以下操作

use Math::Counting ':student';

然后将阶乘方法导出到您的命名空间中,您可以使用它而无需添加整个包名。

于 2012-04-25T15:05:21.633 回答
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
);

所以,看起来作者在这个特定版本中自动导出了他们所有的子例程。作者还定义了两组导出标签:student,和big

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

use Match::Counting qw(:student);

或者

use Math::Counting qw(factorial);
于 2012-04-25T15:58:13.283 回答