Как ссылаться на разделенное выражение в Perl?

Я хочу создать ссылку на массив, полученный разделом в Perl. Я думаю что-то вроде:

my $test = \split( /,/, 'a,b,c,d,e');

foreach $k (@$test) {
   print "k is $k\n";
}

Но это жалуется на Not an ARRAY reference at c:\temp\test.pl line 3. Я попробовал несколько других альтернатив, все без успеха.

Ответы

Ответ 1

Обоснование фона:

split, как и другие функции, возвращает список. Вы не можете ссылаться на список. Однако, если вы применяете ссылочный оператор к списку, он применяется ко всем его членам. Например:

use Data::Dumper;

my @x = \('a' .. 'c');

print Dumper \@x

Вывод:

$VAR1 = [
          \'a',
          \'b',
          \'c'
        ];

Поэтому, когда вы пишете my $test = \split( /,/, 'a,b,c,d,e');, вы получаете ссылку на последний элемент возвращаемого списка (см., например, Какая разница между список и массив?). Ваша ситуация похожа на:

Хотя похоже, что у вас есть список справа, Perl на самом деле видит кучу скаляров, разделенных запятой:

my $scalar = ( 'dog', 'cat', 'bird' );  # $scalar gets bird

Поскольку вы назначаете скаляр, правая сторона находится в скалярном контексте. Оператор запятой (да, его оператор!) В скалярном контексте оценивает свою левую сторону, отбрасывает результат и оценивает его правую сторону и возвращает результат. По сути, этот list-lookalike присваивает $scalar его самое правое значение. Многие люди испортили это, потому что они выбирают список-lookalike, последним элементом которого является также счет, который они ожидают:

my $scalar = ( 1, 2, 3 );  # $scalar gets 3, accidentally

В вашем случае, что вы получаете в RHS, это список ссылок на элементы списка, возвращаемого split, а последний элемент этого списка заканчивается на $test. Сначала вам нужно построить массив из этих возвращаемых значений и взять ссылку на это. Вы можете сделать эту единую инструкцию, сформировав анонимный массив и сохранив ссылку на ссылку $test:

my $test = [ split( /,/, 'a,b,c,d,e') ];

Ответ 2

Окружать split команду между квадратными скобками, чтобы сделать анонимную ссылку.

my $test = [ split( /,/, 'a,b,c,d,e') ];