【问题标题】:Why does my Perl program complain about needing explicit package names?为什么我的 Perl 程序抱怨需要明确的包名?
【发布时间】:2009-09-20 16:55:48
【问题描述】:

我有一个模块 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背景的)

【问题讨论】:

  • zou 可以看出 Perl 与 C 不同,尽管在关键字方面存在误导性的相似性。我的建议是去购买并阅读“Learning Perl”以了解 Perl“思考”的方式。
  • "使用诊断;"会有所帮助

标签: perl variables


【解决方案1】:

$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
);

但是,传入结构以作为参数加载更类似于 C 而不是类似于 Perl。 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";
}

【讨论】:

    【解决方案2】:

    您正在声明哈希 %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
                                          );
    

    package Routines;
    use strict;
    use Exporter;
    
    sub load_shortest_path_matrices {
      my $predecessor_matrix = shift;
      my $shortestpath_matrix = shift;
      ...
    }
    

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

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

    【讨论】:

    • 放弃 &,在这种情况下它是不必要的,并且可能会导致其他问题。除非您知道它的作用以及为什么要使用它,否则切勿在调用的函数中使用 & 前缀。
    • 谢谢,你是对的,我错过了剪切和粘贴 Suan 的代码。
    • @Chas。欧文斯 - 不同意;始终使用 & 没有任何问题(有时是正确的),只要即使没有 args 也使用 ()。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 2011-02-08
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多