Подтвердить что ты не робот

Что это означает, когда вы пытаетесь напечатать массив или хеш с помощью Perl, и вы получите Array (0xd3888)?

Что это означает, когда вы пытаетесь напечатать массив или хеш, и вы увидите следующее: Массив (0xd3888) или HASH (0xd3978)?

Пример

КОД

my @data = (  
['1_TEST','1_T','1_TESTER'],  
['2_TEST','2_T','2_TESTER'],  
['3_TEST','3_T','3_TESTER'],  
['4_TEST','4_T','4_TESTER'],  
['5_TEST','5_T','5_TESTER'],  
['6_TEST','6_T','^_TESTER']  
);  

foreach my $line (@data) {  
   chomp($line);  
   @random = split(/\|/,$line);  
   print "".$random[0]."".$random[1]."".$random[2]."","\n";  
}  

РЕЗУЛЬТАТ

ARRAY(0xc1864)  
ARRAY(0xd384c)  
ARRAY(0xd3894)  
ARRAY(0xd38d0)  
ARRAY(0xd390c)  
ARRAY(0xd3948)  
4b9b3361

Ответ 1

Трудно сказать, имели ли вы в виду это или нет, но причина, по которой вы получаете ссылки на массивы, заключается в том, что вы не печатаете то, что думаете.

Вы начали правильно, перебирая "строки" @data с помощью:

foreach my $line (@data) { ... }

Однако следующая строка не разрешена. Кажется, что вы путаете текстовые строки со структурой массива. Да, каждая строка содержит строки, но Perl рассматривает @data как массив, а не строку.

split используется для преобразования строк в массивы. Он не работает с массивами! То же самое касается chomp (с не относящимся к делу исключением).

То, что вы хотите сделать, это заменить содержимое цикла foreach следующим:

foreach my $line (@data) {

    print $line->[0].", ".$line->[1].", ".$line->[2]."\n";
}

Вы заметите -> запись, которая существует по причине. $line ссылается на массив. Это не сам массив. Стрелки -> обращаются к массиву, позволяя получить доступ к отдельным элементам массива, на которые ссылается $line.

Если вам не нравится идея делать стрелки с помощью стрелок (а большинство начинающих - нет), вы можете создать временный массив, как показано ниже, и использовать его вместо этого.

foreach my $line (@data) {

    my @random = @{ $line };
    print $random[0].", ".$random[1].", ".$random[2]."\n";
}

ВЫХОД

1_TEST, 1_T, 1_TESTER
2_TEST, 2_T, 2_TESTER
3_TEST, 3_T, 3_TESTER
4_TEST, 4_T, 4_TESTER
5_TEST, 5_T, 5_TESTER
6_TEST, 6_T, ^_TESTER

print "@$_\n" for @data; примерно так: print "@$_\n" for @data; (что немного OTT), но если вы хотите просто напечатать массив, чтобы посмотреть, как он выглядит (скажем, для целей отладки), я бы рекомендовал использовать модуль Data::Dump, который симпатично печатает массивы и хэши для вас без необходимости беспокоиться об этом слишком много.

Просто use Data::Dump 'dump'; в начале вашего скрипта, а затем dump @data; , Так просто!

Ответ 2

Это означает, что у вас нет массива; у вас есть ссылка на массив.

Обратите внимание, что массив задается с круглыми скобками - как список; когда вы используете нотацию квадратной скобки, вы создаете ссылку на массив.

foreach my $line (@data)
{
    my @array = @$line;
    print "$array[0] - $array[1] - $array[2]\n";
}

Иллюстрируя разницу:

my @data = (
['1_TEST','1_T','1_TESTER'],
['2_TEST','2_T','2_TESTER'],
['3_TEST','3_T','3_TESTER'],
['4_TEST','4_T','4_TESTER'],
['5_TEST','5_T','5_TESTER'],
['6_TEST','6_T','^_TESTER']
);

# Original print loop
foreach my $line (@data)
{
    chomp($line);
    @random = split(/\|/,$line);
    print "".$random[0]."".$random[1]."".$random[2]."","\n";
}

# Revised print loop
foreach my $line (@data)
{
    my @array = @$line;
    print "$array[0] - $array[1] - $array[2]\n";
}

Выход

ARRAY(0x62c0f8)
ARRAY(0x649db8)
ARRAY(0x649980)
ARRAY(0x649e48)
ARRAY(0x649ec0)
ARRAY(0x649f38)
1_TEST - 1_T - 1_TESTER
2_TEST - 2_T - 2_TESTER
3_TEST - 3_T - 3_TESTER
4_TEST - 4_T - 4_TESTER
5_TEST - 5_T - 5_TESTER
6_TEST - 6_T - ^_TESTER

Ответ 3

Вы печатаете ссылку на хэш или массив, а не на содержимое этого.

В конкретном коде, который вы описываете, я, похоже, помню, что Perl автоматически делает переменную индексации foreach (my $line в вашем коде) в "псевдоним" (вроде того, что я думаю) значения на каждом этапе через цикл.

Итак, $line является ссылкой на @data[x]..., которая на каждой итерации является некоторым массивом. Чтобы попасть в один из элементов @data[0], вам понадобится $ sigil (потому что элементы массива в @data[0] являются скалярами). Однако $line[0] является ссылкой на какую-либо глобальную переменную, которая не существует (use warnings; use strict; сообщит вам об этом, BTW).

[Отредактировано после того, как Эфир указал на мое невежество] @data - список ссылок анонимного массива; каждый из которых содержит список скаляров. Таким образом, вы должны использовать вид явной де-ссылки, описанной ниже:

Что вам нужно, это нечто большее:

print ${$line}[0], ${$line}[1], ${$line}[2], "\n";

... обратите внимание, что ${xxx} [0] гарантирует, что ххх будет детерминирован, тогда индексирование выполняется по результату разыменования, которое затем извлекается как скаляр.

Я также тестирую это:

print $$line[0], $$line[1], $$line[2], "\n";

... и, похоже, это работает. (Тем не менее, я думаю, что первая форма более понятна, даже если она более подробно).

Лично я делаю это до еще одной полученной в Perl.

[Дальнейшая редакция] Я все еще считаю это "gotchya". Подобные вещи и тот факт, что большинство ответов на этот вопрос были технически правильными, в то же время совершенно не демонстрируя никаких усилий, чтобы фактически помочь оригинальному плакату, еще раз напомнил мне, почему я перешел на Python столько лет назад. Код, который я опубликовал, работает, конечно, и, вероятно, выполняет то, что пытался выполнить OP. Мое объяснение было совершенно неправильным. Я видел слово "alias" на странице "perlsyn" man и помнил, что там была какая-то фанковая семантика; поэтому я полностью пропустил ту часть, которая [...] создает анонимную ссылку. Если вы не пьете из Perl Kool-Aid в глубоких сквозняках, то даже самый простой код не может быть объяснен.