Многомерные массивы с использованием целых чисел и строк

Я пытаюсь настроить базовую систему проверки ошибок, в которой она будет обнаруживать ошибки оболочки, запускаемые системным вызовом. execute_command — это функция webmin, которая запускает системный вызов, а затем устанавливает сообщение об ошибке в свой 4-й параметр. В основном я вызываю execute_command_error("adduser test"), зная, что у меня уже есть пользователь с именем test, созданный и основанный на моих предопределенных массивах, я ожидаю, что он напечатает

Невозможно добавить пользователя
Невозможно добавить этого пользователя, поскольку он уже существует в системе.

но вместо этого я получаю:

Уххххххх?
Аххххххх?

Я проверил, что $exe и $return являются «adduser» и 1 соответственно. Что я не понимаю в массивах? Кажется, игнорирует строку и/или число и просто использует последнее определение с 3 элементами. Каково решение этого или лучшее решение?

Вот код:

$ErrorMsg['adduser',1,'title']  = "Unable to add user";
$ErrorMsg['adduser',1,'msg']    = "Unable to add that user because it already exists on the system.";
$ErrorMsg['random',2,'duaisdhai']  = "Uhhhhhhhhh?";

sub execute_command_error
{
    my $error = "";
    my $cmd = $_[0];

    $return = execute_command($cmd, undef, undef, \$error)>>8;
    if ($error) {
        my ($exe) = $cmd =~ m|^(.*?)[ ]|;

        $exe_title = $ErrorMsg[$exe,$return,'title'];
        $exe_msg = $ErrorMsg[$exe,$return,'msg'];


        print $exe_title."<br>";
        print $exe_msg ."<br>";
    }
}

Обновлять:

Я думаю, что мне нужно использовать хэши, я понятия не имею, почему я думал, что могу использовать строки в индексах. С учетом сказанного, небольшое исследование привело меня к чему-то вроде этого:

%ErrorMsgs =    ('adduser' =>   {
                '1' =>  {
                    'title' =>  'Unable to add user',
                    'msg'   =>  'Unable to add that user because it already exists on the system.',
                },
            },
            );

Теперь, как я могу ссылаться на него, используя переменную? потому что ни один из них не работает:

    $exe_title = $ErrorMsgs{"$exe"}{"$return"}{"title"};
    $exe_title = $ErrorMsgs{$exe}{$return}{title};

person ParoX    schedule 01.07.2009    source источник


Ответы (2)


Во-первых, см. perldsc, чтобы узнать о правильном синтаксисе для создания многомерных структур. Ваши массивы не имеют никакого смысла.

Если бы у вас были включены предупреждения, вы бы увидели предупреждение "Аргумент не числовой". чтобы сказать вам, что вы не можете использовать строки каким-либо осмысленным образом в индексе массива.

Но хеш, который вы разместили в своем обновлении, должен работать нормально.

#!/usr/bin/perl

use strict;
use warnings;
## ^^ these things are your friends

my %ErrorMsgs =    ('adduser' =>   {
                        '1' =>  {
                                'title' =>      'Unable to add user',
                                'msg'   =>      'Unable to add that user because it already exists on the system.',
                        },
                },
                );

my $exe = 'adduser';
my $return = 1;

print $ErrorMsgs{$exe}{$return}{title};    # works

Если вы не получаете ожидаемого вывода, это связано с тем, что что-то не так с $exe или $return — возможно, они не определены в той области, в которой вы пытаетесь их использовать. Включение strict и предупреждений поможет отследить проблему.

person friedo    schedule 01.07.2009

{ 'key' => 'val' } создает хеш-ссылку, поэтому вы разыменовываете перед поиском ключа.

$exe_title = $ErrorMsgs{$exe}->{$return}->{"title"};

Вам также не нужно заключать в кавычки $exe или $return, так как они уже содержат строки.

Обратите внимание, что Perl не поддерживает многомерные индексы; многомерный массив — это просто массив массивов, поэтому вам нужно использовать [] для каждого индекса. В скалярном контексте оператор запятой возвращает значение самого правого выражения, поэтому следующие строки эквивалентны:

$ErrorMsg[0,1,2]  = "foo";
$ErrorMsg[2]  = "foo";

Обратите внимание, что в контексте списка оператор запятой возвращает список значений, который дает нам срезы:

@a=qw(f o o);
@a[3,4,5] = qw(b a r);
print join(',', @a), "\n";
# output: f,o,o,b,a,r 
@ErrMsg{qw(title msg)} = ('Unable to add user', 'Unable to add that user because it already exists on the system.')
person outis    schedule 01.07.2009