in reply to Getting for() to accept a tied array in one statement

Is it an absolute requirement to have all the code within the while/for expression? I.e. is the following acceptable:
my $iter = TQDM::tqdm(1..10); while (<$iter>) { print "got [$_]\n"; }
If so, then the behaviour you want is easily achieved using overloaded '<>'.

Otherwise, I think you need a custom iterator function, e.g.

sub iterate ($&) { my ($ary, $code) = @_; for (@$ary) { print "progress bar: $_\n"; $code->(); } } sub tqdm { bless [ @_ ] } iterate tqdm(1..10), sub { print "got [$_]\n"; };

Dave.

Replies are listed 'Best First'.
Re^2: Getting for() to accept a tied array in one statement
by perlancar (Hermit) on Apr 16, 2019 at 14:22 UTC

    Yes, in this case the goal is on how easy it is to add a progress indicator to an existing code that uses for(). If a user has to change her for() to while(), that would count as less easy. It's akin in spirit to data dumping modules like XXX or Data::Dmp that returns its original argument so you can insert XXX or dmp just about anywhere in an existing Perl code.

    Next step after I conquer for(), will probably move on to while(). :-) Yes, I'll be looking into overloading the diamond operator or tying filehandle.

      I don't think its possible in perl to write a function foo() that will allow any of the following in the way you want:
      for (foo(list)) { ... } while (foo(list)) { .... } while (<foo(list)>) { .... }
      assuming that for and while are the perl built-ins, and that you're not using source filtering or keyword plugins etc.

      Dave.