Что это означает, когда вы пытаетесь напечатать массив или хеш с помощью 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)
Ответы
Ответ 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 в глубоких сквозняках, то даже самый простой код не может быть объяснен.