That is interesting. One change I'd suggest would be to not say
if @foo, since that will result in the iterator returning 0 (
@foo in scalar context) when the list is exhausted. Unconditionally saying
shift @foo will return undef instead, which, while still ambiguous if
@foo may contain undef, is more what I'd expect.
Either way, your iterator is only expecting to be called in scalar context; you could expand it to allow returning the remaining list when the iterator is called in list context:
sub foo {
# ...
wantarray ? @foo : sub { wantarray ? splice @foo : shift @foo } };
}
(It is a little inconsistent to use
return in sub foo but not in the anonymous sub.)