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

Sua*_*uan 0 variables perl

我有一个模块Routines.pm:

package Routines;
use strict;
use Exporter;

sub load_shortest_path_matrices {
  my %predecessor_matrix = shift;
  my %shortestpath_matrix = shift;
  ...
}
Run Code Online (Sandbox Code Playgroud)

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

use Routines;
use strict;

my %predecessor_matrix = ();
my %shortestpath_matrix =();  
&Routines::load_shortest_path_matrices($predecessor_matrix, $shortestpath_matrix);
Run Code Online (Sandbox Code Playgroud)

但是,这不编译,我得到

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

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

Cha*_*ens 14

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

此外,您的功能有问题.它希望能够从@_得到两个哈希值,但在列表环境中(如在函数的参数列表)的散列产生键值对的列表.所以,无论是%predecessor_matrix%shortestpath_matrix将在风%predecessor_matrix的作用的.你需要做的是使用参考:

package Routines;
use strict;
use Exporter;

sub load_shortest_path_matrices {
    my $predecessor_matrix  = shift;
    my $shortestpath_matrix = shift;
    $predecessor_matrix->{key} = "value";
    ...
}
Run Code Online (Sandbox Code Playgroud)

use Routines;
use strict;

my %predecessor_matrix; 
my %shortestpath_matrix;  
Routines::load_shortest_path_matrices(
    \%predecessor_matrix,
    \%shortestpath_matrix
);
Run Code Online (Sandbox Code Playgroud)

但是,传入结构作为参数加载比类似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;
}
Run Code Online (Sandbox Code Playgroud)

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";
}
Run Code Online (Sandbox Code Playgroud)


lex*_*exu 5

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

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

例程:: 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
                                      );
Run Code Online (Sandbox Code Playgroud)
package Routines;
use strict;
use Exporter;

sub load_shortest_path_matrices {
  my $predecessor_matrix = shift;
  my $shortestpath_matrix = shift;
  ...
}
Run Code Online (Sandbox Code Playgroud)

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

my $foobar=$shortestpath_matrix->{FOOBAR};
Run Code Online (Sandbox Code Playgroud)

  • 放弃&,在这种情况下是不必要的,并且可能导致其他问题.除非您知道它的作用以及您想要使用它的原因,否则切勿对调用的函数使用&前缀. (6认同)