Как упомянуто ранее, for (каждый) - активный цикл, поэтому он хочет оценить весь список перед запуском.
Для простоты я бы рекомендовал использовать объект итератора или замыкание, а не пытаться получить лениво вычисляемый массив. В то время как вы можете использовать привязку для лениво оцененного бесконечного списка, вы можете столкнуться с проблемами, если когда-нибудь попросите (прямо или косвенно, как в предыдущем разделе) весь список (или даже размер весь список).
Без написания полного класса или использования каких-либо модулей вы можете создать простую фабрику итераторов, просто используя замыкания:
sub make_iterator {
my ($value, $max, $step) = @_;
return sub {
return if $value > $max; # Return undef when we overflow max.
my $current = $value;
$value += $step; # Increment value for next call.
return $current; # Return current iterator value.
};
}
А затем использовать его:
# All the even numbers between 0 - 100.
my $evens = make_iterator(0, 100, 2);
while (defined( my $x = $evens->() ) ) {
print "$x\n";
}
В CPAN также есть модуль Tie :: Array :: Lazy , который обеспечивает более богатый и полный интерфейс для ленивых массивов. Я не использовал модуль сам, поэтому ваш пробег может отличаться.
Всего наилучшего,
Пол