Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

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

by LanX (Saint)
on Apr 18, 2019 at 14:19 UTC ( [id://1232760]=note: print w/replies, xml ) Need Help??


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

tie @ary, "My::Class", "some", "el", "ems"; for (@ary) { some_code($_); }

What if the loop is left by last , next , redo , return or goto ?

Does the code hooked into the tied array really catch all edge cases sufficiently for your progress-bar?

edit

Is there any ->DESTROY of the tied class being called?

NB: As already told, be aware about restrictions on Perl versions.

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Replies are listed 'Best First'.
Re^2: Getting for() to accept a tied array in one statement
by haukex (Archbishop) on Apr 18, 2019 at 20:11 UTC
    Is there any ->DESTROY of the tied class being called?

    It depends where the @ary is defined. In the solution suggested by hdb, there is a DESTROY:

    use warnings; use strict; print "--- Begin loop ---\n"; for ( @{ tie my @ary, 'MyArray', qw/ x y z /; \@ary } ) { print "<$_>\n"; last if /y/; } print "--- End loop ---\n"; BEGIN { package MyArray; sub TIEARRAY { my $c = shift; bless { arr=>[@_] }, $c } # largely borrowed from Tie::StdArray sub FETCH { $_[0]{arr}[$_[1]] } sub STORE { $_[0]{arr}[$_[1]] = $_[2] } sub FETCHSIZE { scalar @{$_[0]{arr}} } sub STORESIZE { $#{$_[0]{arr}} = $_[1]-1 } sub EXTEND { $#{$_[0]{arr}} = $_[1]-1 } sub CLEAR { @{$_[0]{arr}} = () } sub POP { pop @{$_[0]{arr}} } sub SHIFT { shift @{$_[0]{arr}} } sub PUSH { my $o=shift; push @{$$o{arr}}, @_ } sub UNSHIFT { my $o=shift; unshift @{$$o{arr}}, @_ } sub EXISTS { exists $_[0]{arr}[$_[1]] } sub DELETE { delete $_[0]{arr}[$_[1]] } sub UNTIE { %{$_[0]}=(); return } sub DESTROY { %{$_[0]}=(); return } sub SPLICE { my $ob = shift; my $sz = $ob->FETCHSIZE; my $off = @_ ? shift : 0; $off += $sz if $off < 0; my $len = @_ ? shift : $sz-$off; return splice(@{$$ob{arr}}, $off, $len, @_); } # debug stuff: use Class::Method::Modifiers qw/around/; use Data::Dump qw/pp/; my @m = qw/ CLEAR DELETE DESTROY EXISTS EXTEND FETCH FETCHSIZE POP PUSH SHIFT SPLICE STORE STORESIZE TIEARRAY UNSHIFT UNTIE /; for my $m (@m) { around $m => sub { my $orig = shift; my $self = shift; my @args = @_; if (wantarray) { my @rv = $orig->($self, @_); print STDERR $m," ",pp(@args)," => ",pp(@rv),"\n"; return @rv; } # else my $rv = $orig->($self, @_); print STDERR $m," ",pp(@args)," => ",pp($rv),"\n"; return $rv; }; } } __END__ --- Begin loop --- TIEARRAY ("x", "y", "z") => bless({ arr => ["x", "y", "z"] }, "MyArray +") FETCHSIZE () => 3 FETCH 0 => "x" <x> FETCHSIZE () => 3 FETCH 1 => "y" <y> DESTROY () => undef --- End loop ---
      Haven't tested it yet but your results look convincing. :)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re^2: Getting for() to accept a tied array in one statement
by perlancar (Hermit) on Apr 22, 2019 at 07:41 UTC
    What if the loop is left by last , next , redo , return or goto ?

    Nice catch. In the Python library, this must be handled explicitly by "closing" the iterator.

      > In the Python library, this must be handled explicitly

      LOL...

      well hooking into DESTROY should handle this implicitly.

      BTW: I forgot to list die and exception handling.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1232760]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-04-18 05:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found