На днях нужно было перебирать подмножество массива за раз. Первоначально я делал это с помощью сплайсинга - в этом случае не было проблем с разрывом массива. Он будет возвращать N элементов за раз, или что-то еще, что осталось в конце списка. Все прошло хорошо.
Тогда оказалось, что мне нужен массив позже. Вместо сращивания я переключился на срезы массива. БУМ! Программа взорвалась, отправив переполнение стека везде. Какие? Зачем? Как? Я поиграл с этим, и нашел пару вариантов, которые будут работать. Вот тестовый скрипт для демонстрации этой проблемы:
use strict;
use warnings;
my @array = qw(a b c d e f g h i j k l m n o p q r s t u v z x c v b a s d f g a s d f a se g);
my $numPerTest = 5;
my $index = 0;
print "Separating out the subset before grepping it, good.\n";
while ($index < @array)
{
print "Iteration $index\n";
my @subset = @array[$index..($index+$numPerTest)];
@subset = grep { defined $_ } @subset;
$index += $numPerTest;
}
$index = 0;
print "Making a copy of the array before grepping works.\n";
while ($index < @array)
{
print "Iteration $index\n";
my @subset = grep { defined $_ } @{[ @array[$index..($index+$numPerTest)] ]};
$index += $numPerTest;
}
$index = 0;
print "Grepping the array slice directly, explodey!\n";
while ($index < @array)
{
print "Iteration $index\n";
my @subset = grep { defined $_ } @array[$index..($index+$numPerTest)];
$index += $numPerTest;
}
1005
(Также, если вы этого не видите, у этого есть другой способ объяснить, почему это происходит.)