Почему моя Perl-программа жалуется на необходимость явных имен пакетов? - PullRequest
0 голосов
/ 20 сентября 2009

У меня есть модуль 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);

Однако, это не компилируется, и я получаю

Для глобального символа "$ precessor_matrix" требуется явное имя пакета

тип ошибок. Разве нельзя дать одно и то же имя переменным в разных областях, как это в Perl? (Я из C фона)

Ответы [ 2 ]

14 голосов
/ 20 сентября 2009

$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";
    ...
}

и

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";
}
5 голосов
/ 20 сентября 2009

вы объявляете хеш% precessor_matrix, но пытаетесь передать скалярную $ precessor_matrix. Хеш существует, скаляр отсутствует.

Может быть, вы хотите передать ссылки на хэши?

Подпрограммы :: load_shortest_path_matrices (\% precessor_matrix, \% shorttestpath_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};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...