Perl- разыменование arrayref и присвоение результата переменной приводит к переменной со значением 1

Я пытаюсь проанализировать строку журнала, которая входит в мой сценарий как ссылку на массив.

У меня есть другая подпрограмма, в которую эта строка журнала передается для извлечения определенного значения, однако функция, похоже, не получает строку журнала, а вместо этого получает значение 1. Это происходит, когда я пытаюсь разыменовать массив ref и назначить его скаляр тоже.

Строка журнала выглядит как -

print Dumper ($logline)

$VAR1 = '2013-06-07 17:22:32.219 <TID 1B344> [uss_smm.reqserv] 162.34.22.1: "POST /ts/start/67257-v/827987/ts/june7test1/backup/20130fd83788-02-ts&action=setarchiver&timestamp=1370625752.172546&as=new2 HTTP/1.1" 200 - Success.';

Assigning the dereferenced value to scalar -
my $temp_line = @{ $logline };
print "temp_line is $temp_line \n";

temp_line is 1

Вызов подпрограммы -

my $arch = parse_Smmlog_Arch_Comm(@{ $logline }); 

Подпрограмма для разбора -

sub parse_Smmlog_Arch_Comm($){
    my $logline = shift;
    print Dumper ($logline);
    test_log(INFO,"in parse_Smmlog_Arch(), logline is  - $logline ");
    my @arr = split('&as=',$logline);
    my @sec_arr = split(' ',$arr[1]);
    return $sec_arr[0];
}

Я получаю это при запуске сценария, потому что подпрограмма не получает строку журнала.

Use of uninitialized value in split at /Users/myname/parseLog.pl

Буду признателен за любую помощь в этом.

2 ответа

Решение

$logline не ссылка на массив, это простая строка.

Однако вы рассматриваете его как ссылку на массив, поэтому он ищет переменную массива следующим образом:

@{'2013-06-07 17:22:32.219 <TID 1B344> [uss_smm.reqserv] 162.34.22.1: "POST /ts/start/500000-b/500000/ts/june7test1/backup/20130607T102446-02-ts&action=setarchiver&timestamp=1370625752.172546&as=new2 HTTP/1.1" 200 - Success.'}

который бы потерпел неудачу под use strict (что удерживает вас от случайного использования символических ссылок, подобных этой). Вы должны включить use strict; а также use warnings; во всем вашем коде поймать много простых ошибок.

Даже если это была ссылка на массив, этот код:

my $temp_line = @{ $logline };

назначает количество элементов в массиве $temp_line; поскольку вы получаете 1, вы случайно используете ту же символьную ссылку где-то еще и фактически создаете и заполняете массив причудливым именем.

Чтобы получить первый элемент массива, выполните:

${ $logline }[0]

или чтобы получить его при удалении из массива, выполните:

shift @{ $logline }

В общем, использование ссылок только немного сложнее, чем использование простых массивов или хэшей; см. http://perlmonks.org/?node=References+quick+reference чтобы ознакомиться с некоторыми легко запоминающимися правилами.

Проблема, вероятно, связана с вашим прототипом функции:

sub parse_Smmlog_Arch_Comm($)

что означает, что он ожидает скаляр. Когда вы передаете массив, а именно @{ $logline }, массив оценивается в скалярном контексте, давая вам количество элементов в этом массиве, которое равно 1.

Когда вы делаете первый splitничего не получаешь, так @arr пусто, что приводит к uninitialized value ошибка на втором split,

Замена $ с @ или удаление ($) из определения функции решит проблему. В качестве альтернативы, передайте скаляр в качестве аргумента функции.


Sidenote: вероятно, не очень хорошая идея иметь одно и то же имя переменной, означающее разные вещи внутри и снаружи функции (строка внутри, ссылка на массив снаружи)

Другие вопросы по тегам