为什么我的Perl程序抱怨需要显式的包名?

时间:2009-09-20 16:55:48

标签: perl variables

我有一个模块Routines.pm:

package Routines;
use strict;
use Exporter;

sub load_shortest_path_matrices {
  my %predecessor_matrix = shift;
  my %shortestpath_matrix = shift;
  ...
}

从另一个脚本我调用模块中的sub,传入恰好具有相同名称的参数:

use Routines;
use strict;

my %predecessor_matrix = ();
my %shortestpath_matrix =();  
&Routines::load_shortest_path_matrices($predecessor_matrix, $shortestpath_matrix);

然而,这不会编译,我得到

全局符号“$ predecessor_matrix”需要显式包名称

错误类型。在Perl中不可能给不同范围的变量赋予相同的名称吗? (我来自C背景)

2 个答案:

答案 0 :(得分:14)

$predecessor_matrix是一个标量,%predecessor_matrix是一个哈希值。 Perl中的不同类型(标量,数组,散列,函数和文件句柄)在符号表中具有不同的条目,因此可以具有相同的名称。

此外,您的功能有问题。它希望能够从@_获得两个哈希值,但列表上下文中的哈希值(例如在函数的参数列表中)会产生一个键值对列表。因此,%predecessor_matrix%shortestpath_matrix都会在函数的%predecessor_matrix中结束。您需要做的是使用references

package Routines;
use strict;
use Exporter;

sub load_shortest_path_matrices {
    my $predecessor_matrix  = shift;
    my $shortestpath_matrix = shift;
    $predecessor_matrix->{key} = "value";
    ...
}

use Routines;
use strict;

my %predecessor_matrix; 
my %shortestpath_matrix;  
Routines::load_shortest_path_matrices(
    \%predecessor_matrix,
    \%shortestpath_matrix
);

但是,传入结构作为参数加载比类似Perl更像C。 Perl可以返回多个值,因此更常见的是看到如下代码:

package Routines;
use strict;
use Exporter;

sub load_shortest_path_matrices {
    my %predecessor_matrix;
    my %shortestpath_matrix;
    ...
    return \%predecessor_matrix, \%shortestpath_matrix;
}

use Routines;
use strict;

my ($predecessor_matrix, $shortestpath_matrix) =
    Routines::load_shortest_path_matrices();

for my $key (keys %$predecessor_matrix) {
    print "$key => $predecessor_matrix->{$key}\n";
}

答案 1 :(得分:5)

您正在声明哈希%predecessor_matrix,但正在尝试传递标量$ predecessor_matrix。哈希存在,标量不存在。

也许你想传递对哈希的引用?

Routines :: load_shortest_path_matrices(\%predecessor_matrix,\%shortestpath_matrix);


这是另一种编码方式:

use strict;
use warnings;
use Routines;

my $predecessor_matrix = {};
my $shortestpath_matrix ={};  
Routines::load_shortest_path_matrices(  $predecessor_matrix
                                       , $shortestpath_matrix
                                      );

package Routines;
use strict;
use Exporter;

sub load_shortest_path_matrices {
  my $predecessor_matrix = shift;
  my $shortestpath_matrix = shift;
  ...
}

您可以像这样访问哈希的内容

my $foobar=$shortestpath_matrix->{FOOBAR};