我想在Perl中克隆一个生成器(Coro :: Generator)状态。例如:在下面的代码中,我有一个迭代数组的生成器:
use Coro::Generator;
sub iterate_array {
my @arr = @{ $_[0] };
generator {
foreach my $value (@arr) {
# Each time function is called it returns the next value in the array
yield $value;
}
yield undef;
};
}
my @a = (1,2,3,4);
my $iterator = iterate_array(\@a);
print $iterator->(); # output: 1
因此输出为1.如果再次调用则为2(数组中的第2项)。
我现在想要克隆迭代器的状态。类似的东西:
my $clone = clone($iterator); # Clone iterator
print $iterator->(); # output: 2
print $clone->(); # output: 2
$ clone和$ iterator产生的结果与它们的克隆相同。
我尝试过使用Storable包,即:
use Storable 'dclone';
my $clone = dclone($iterator);
但这会产生错误:
Can't store CODE items at ...
任何帮助都非常感激。
答案 0 :(得分:0)
Coro::Generator
模块预计不会克隆迭代器:
但是,我们可以通过缓存迭代器的结果来“克隆”自己:
sub clone_iter {
my ($n, $iter) = @_;
my @caches;
my $make_subiterator = sub {
# each subiterator has its own cache of not-yet seen items
my $cache = [];
push @caches, $cache;
return sub {
# If *our* cache is empty…
if (not @$cache) {
my $result = $iter->();
# add this result to *all* caches
push @$_, \$result for @caches;
}
return ${ shift @$cache };
};
};
return map { $make_subiterator->() } 1 .. $n;
}
my $i = 1;
my $iter = sub { $i++ }; # just for testing
my ($iter_a, $iter_b, $iter_c) = clone_iter(3, $iter);
say join ' ', map { $iter_a->() } 1 .. 3;
say join ' ', map { $iter_b->() } 1 .. 7;
say join ' ', map { $iter_a->() } 4 .. 10;
say join ' ', map { $iter_c->() } 1 .. 7;
示例输出:
1 2 3
1 2 3 4 5 6 7
4 5 6 7 8 9 10
1 2 3 4 5 6 7