Если вы вызываете кнопку с списком аргументами, вы добавляете первый список с остающимся списком (ов) в стеке мудрой моде. Читайте о нажатии на Perldoc. Таким образом, ваш звонок push(@table, @row);
создает более длинный список @table
, а не двухмерный массив.
Вы получили несколько сообщений, которые нажимают ссылку на список @row
, так как \@row
создаст список строк, и это действительно работает. Я имею тенденцию делать это немного по-другому.Конечно, с Perl всегда есть другой способ сделать это!
Синтаксически вы также можете нажать ссылку на анонимный массив в скалярном элементе списка, чтобы создать список с несколькими измерениями. Самое важное, что нужно знать о ссылках в Perl, это: 1) они являются скалярами и 2) они могут ссылаться на что-либо в Perl-коде, массиве, хэше, другой ссылке. Проведите некоторое время с Perl Ref Tutorial, и это станет более понятным. С вашим кодом просто добавьте [ ]
вокруг элемента, который вы хотите быть вторым измерением в своем списке, поэтому push(@table, @row);
должен быть push(@table, [ @row ]);
В том же смысле вы помещаете [ ]
вокруг своего разбиения так, чтобы оно становилось push(@table, [ split(/\s*,\s*/, $_) ]);
. Это будет одновременно выполнять разделение и создавать анонимный массив к результату.
Конкретная проблема, с которой вы сталкиваетесь, как создать и получить доступ к многомерному списку, также очень хорошо разбирается в Тома Кристенсена perllol tutorial Решения по вашим конкретным вопросам с вашим кодом напрямую рассматриваются здесь.
Переписывая код с точным кодом из примера Тома в perllol, он становится этим:
#!/usr/bin/perl
use strict;
use warnings;
my (@row, @table, $n, $rowref);
while(<DATA>) {
chomp;
# regex to separate CSV (use of a cpan module for CSV STRONGLY advised...
@row = /(?:^|,)("(?:[^"]+|"")*"|[^,]*)/g;
for (@row) {
if (s/^"//) { s/"$//; s/""/"/g; }
}
push(@table, [ @row ]); #Note the [ ] around the list
}
# Now the table is created, print it:
my $rowcnt=0;
foreach $rowref (@table) {
print "row $rowcnt:\n";
$rowcnt++;
print " [ @$rowref ], \n";
}
# You can access the table in the classic [i][j] form:
for my $i (0 .. $#table) {
$rowref = $table[$i];
$n = @$rowref - 1;
for my $j (0 .. $n) {
print "element $i, $j of table is $table[$i][$j]\n";
}
}
# You can format it:
for my $i (0 .. $#table) {
print "$table[$i][0] $table[$i][1]\n";
print "$table[$i][2]\n";
print "$table[$i][3], $table[$i][4] $table[$i][5]\n\n";
}
__DATA__
Mac,Doe,120 jefferson st.,Riverside, NJ, 08075
Jack,McGinnis,220 hobo Av.,Phila, PA,09119
"John ""Da Man""",Repici,120 Jefferson St.,Riverside, NJ,08075
Stephen,Tyler,"7452 Terrace ""At the Plaza"" road",SomeTown,SD, 91234
,Blankman,,SomeTown, SD, 00298
"Joan ""Joan, the bone""",Jett,"9th, at Terrace plc",Desert City,CO,0
+1 за не тратить время каждого опуская 'использовать строгий; использовать предупреждения; '. – Ether
Вы должны действительно избегать 2 аргументов 'open'. У него есть ряд проблем, которые лучше всего избегать (для обсуждения см. Эту публикацию 2001 года perlmonks: http://www.perlmonks.org/?node_id=131085). См. Эту публикацию SO для информации о лексических дескрипторах: http: // stackoverflow .com/questions/613906/why-do-programming-perl-use-local-not-my-for-filehandles – daotoad
См. ['perldoc perllol'] (http://perldoc.perl.org/perllol.html#Access -and-Printing). Доступ и печать – Zaid