Есть ли способ заставить Perl вызывать FETCHSIZE
для связанного массива перед каждым вызовом FETCH
? Мой связанный массив знает его максимальный размер, но может уменьшиться от этого размера в зависимости от результатов более ранних вызовов FETCH
. Вот надуманный пример, который фильтрует список только по четным элементам с отложенной оценкой:
use warnings;
use strict;
package VarSize;
sub TIEARRAY { bless $_[1] => $_[0] }
sub FETCH {
my ($self, $index) = @_;
splice @$self, $index, 1 while $$self[$index] % 2;
$$self[$index]
}
sub FETCHSIZE {scalar @{$_[0]}}
my @source = 1 .. 10;
tie my @output => 'VarSize', [@source];
print "@output\n"; # array changes size as it is read, perl only checks size
# at the start, so it runs off the end with warnings
print "@output\n"; # knows correct size from start, no warnings
для краткости я опустил кучу кода проверки ошибок (например, как обрабатывать доступы, начиная с индекса, отличного от 0)
РЕДАКТИРОВАТЬ: вместо двух вышеприведенных операторов печати, если используется ОДНА из следующих двух строк, первая будет работать нормально, а вторая будет выдавать предупреждения.
print "$_ " for @output; # for loop "iterator context" is fine,
# checks FETCHSIZE before each FETCH, ends properly
print join " " => @output; # however a list context expansion
# calls FETCHSIZE at the start, and runs off the end
Обновление:
Фактический модуль, который реализует связанный массив переменного размера, называется List :: Gen , который работает на CPAN. Функция filter
, которая ведет себя как grep
, но работает с ленивыми генераторами List::Gen
. У кого-нибудь есть идеи, которые могли бы сделать реализацию filter
лучше?
(функция test
аналогична, но возвращает undef
в сбойных слотах, сохраняя размер массива постоянным, но, конечно, семантика использования отличается от grep
)