への各呼び出しの前に、 Perl にFETCHSIZE
tie された配列を強制的に呼び出す方法はあります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 以外のインデックスから始まるアクセスの処理方法など)。
編集: 上記の 2 つの print ステートメントではなく、次の 2 行のいずれかを使用すると、最初の行は正常に動作し、2 番目の行は警告をスローします。
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
)