in reply to Re: Doing "it" only once
in thread Doing "it" only once

cog,
Yes of course, in this situation. The reason it works is because file handles are iterators remembering where they left off and because our condition was simple. There are far more situations in which it wouldn't work so the meditation is on the idea of dynamically splicing in code blocks while code is running and what neat things might you do if the functionality existed without heavy penalties.

Cheers - L~R

Replies are listed 'Best First'.
Re^3: Doing "it" only once
by Anonymous Monk on Sep 21, 2005 at 15:52 UTC
    Eh, I've a hard time believe there exists a situation where it [statically splicing the code, as in cog's solution] wouldn't work, but where it's still possible to dynamically splicing in code blocks while code is running.

    Could you give an example of such code?

    BTW, what you are asking for is a special case of "loop enlightment", and cog's solution is the standard way of solving this. It belongs in Programming 102.

      Anonymous Monk,
      No, what I am asking for is not a special case of "loop enlightment". What I am asking for is for people to consider what they would do if they had the ability to modify the optree (or the p6 equivalent) while the code is running.

      To answer you code question - consider the following trivial example:

      for ( @some_array ) { if ( $_ eq 'foo' ) { print "skipping foo\n"; next; } if ( $_ eq 'bar' ) { handle_bar($_); next; } handle_rest($_); }
      To re-write this we need to first change
      for ( @some_array ) { ... } # to my $index = -1; while ( ++$index <= $#some_array ) { ... }
      So that when we break out of the first loop to enter the second, we can remember where we left off. Unfortunately, the order that we will encounter 'foo' and 'bar' is unknown so we also have to create a flag variable and end up with 4 while loops instead of the original 1: This was a translation of a very simple example. I do not if there is any case where it would be impossible to do, but it certainly isn't easy. Again, the point of the medidation is to just take the functionality as a given for a second and think about what you would do with it.

      Cheers - L~R

        I think you want the match-only-once operator:
        for ( @some_array ) { if ( ?^foo$? ) { print "skipping foo\n"; next; } if ( ?^bar$? ) { handle_bar($_); next; } handle_rest($_); }

        Caution: Contents may have been coded under pressure.
        my %things = (foo => sub {print "skipping foo\n"; next}, bar => sub {handle_bar($_); next}, ); for (@some_array) { (delete $things{$_})->() if exists $things{$_}; handle_rest($_); }