未定义的子程序& PDL :: divide

时间:2014-06-30 16:32:56

标签: perl perl-module pdl

我正在使用以下代码尝试Perl的PDL:

#!/usr/bin/perl  -w
use strict;
use PDL::Core qw(pdl);
use PDL::Math qw(isfinite);
use PDL::Primitive qw(statsover);


my $div = 4;
my @array1 = (0..10);
my $pdl_array = log(pdl(@array1)/$div);
$pdl_array->where(!isfinite($pdl_array)) .= 0;
my($mean,$stdev) = statsover($pdl_array);
die $pdl_array,"\n",$mean," ",$stdev,"\n";

我收到了这个错误:

未定义的子程序& PDL :: divide在./compare_const.pl第10行调用。

请提示吗?非常感谢。

3 个答案:

答案 0 :(得分:4)

PDL在设计上是不寻常的,因此具有不寻常且有些脆弱的导入机制。每个PDL模块通过inserting a new method directly into PDL's package向PDL添加功能。这个决定是在PDL v2设计的早期阶段做出的,并且在这十年间没有改变。 (即使以向后兼容的方式,也没有理由不改变它,但是没有一个PDL开发人员留出时间这样做。)

因此,您必须加载一些模块以确保PDL具有必需的基本功能。如果您查看PDL的导入功能,您会注意到it explicitly loads a number of packages into the caller's namespace。这样做的原因很好 - 跨多个模块分离功能以保持分布正常 - 但实现与常见的Perl实践不一致。这就是您尝试将特定函数导入命名空间失败的原因。

解决方案已经解释过了。使用单个use PDL::...替换所有use PDL语句:

use strict;
use warnings;
use PDL;

my $div = 4;
...

或说use PDL::Lite(以确保PDL的软件包已完成),然后将特定功能导入您的(主)软件包

use strict;
use warnings;

use PDL::Lite;
use PDL::Core qw(pdl);
use PDL::Math qw(isfinite);
use PDL::Primitive qw(statsover);

my $div = 4;
...

答案 1 :(得分:1)

PDL有一组必须加载的东西。要正确加载这些内容,您必须use PDL(也导​​出一堆内容)或use PDL::Lite

(我出于某种原因认为你明确地直接调用了PDL :: divide并得到了这个错误,因此我的原始答案如下。)

原始答案:

我想知道为什么你认为应该工作?

是的,PDL导出一堆东西(如果你使用它,你没有),但是这并不能保证从导出它的位置。 (事实上​​,它似乎从许多不同的地方直接导入到使用包中。)

如果你试图避免命名空间污染,我建议你导入指定的包并使用那里的东西:

{
    package My::PDL;
    use PDL;
}
...
My::PDL::divide...

或使用OO界面(参见PDL :: Lite,我认为?)

答案 2 :(得分:1)

只需添加use PDL;,您的代码即可运行:

#!/usr/bin/perl  -w
use strict;

use PDL;
use PDL::Core qw(pdl);
use PDL::Math qw(isfinite);
use PDL::Primitive qw(statsover);

my $div = 4;
my @array1 = (0..10);
my $pdl_array = log( pdl(@array1) / $div );
$pdl_array->where(!isfinite($pdl_array)) .= 0;
my ($mean, $stdev) = statsover($pdl_array);
die $pdl_array, "\n", $mean, " ", $stdev, "\n";

输出:

[0 -1.3862944 -0.69314718 -0.28768207 0 0.22314355 0.40546511 0.55961579 0.69314718 0.81093022 0.91629073]
0.112860814716055 0.696414187766251