but how to emulate the style of a Python library.
I presume Python's has native support for iterators. Perl 6 has lazy lists, but Perl 5's doesn't, and nothing's going to make for work with lazy lists short of overriding for/foreach. Tied arrays definitely can't achieve that.
There are a few modules that provide iterator-aware looping primitives. Search for "iterator" on CPAN.
With for(@tied_array) we also doesn't need to calculate the length of the list in advance
That's not true.
Whether it's called for every loop pass or not, it's still called before the first pass, so you still need to know the size up front. And FETCHSIZE must always return a correct value because it's called once in other situations.
In fact, I consider it a bug that FETCHSIZE is called more than once in that situation.
Ironically, if you circumvent the optimisation of for (@a) by using for ((), @a), you actually get something faster for tied arrays since the latter only calls FETCHSIZE once.
BEGIN { package My::TiedArray; use strict; use warnings; use Tie::Array qw( ); our @ISA = 'Tie::StdArray'; sub TIEARRAY { my $class = shift; bless [@_], $class } sub FETCHSIZE { my $self = shift; print("FETCHSIZE\n"); return $self->SUPER::FETCHSIZE(@_); } $INC{"My/TiedArray.pm"} = 1; } use strict; use warnings; use feature qw( say ); use My::TiedArray qw( ); tie my @a, My::TiedArray::, qw( a b c ); say "Before loop"; for (@a) { say "In Loop"; } say ""; say "Before loop"; for ((), @a) { say "In Loop"; }
Before loop FETCHSIZE In Loop FETCHSIZE In Loop FETCHSIZE In Loop FETCHSIZE Before loop FETCHSIZE In Loop In Loop In Loop
In reply to Re^9: Getting for() to accept a tied array in one statement
by ikegami
in thread Getting for() to accept a tied array in one statement
by perlancar
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |