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

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:
my $flag; my $index = -1; while ( ++$index <= $#some_array ) { if ( $_ eq 'foo' ) { $flag = 'foo'; print "skipping foo\n"; last; } if ( $_ eq 'bar' ) { $flag = 'bar'; handle_bar($_); last; } handle_rest($_); } if ( $flag eq 'foo' ) { while ( ++$index <= $#some_array ) { if ( $_ eq 'bar' ) { handle_bar($_); last; } handle_rest($_); } } else { while ( ++$index <= $#some_array ) { if ( $_ eq 'foo' ) { print "skipping foo\n"; last; } handle_rest($_); } } while ( ++$index <= $#some_array ) { handle_rest($_); }
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

Replies are listed 'Best First'.
Re^5: Doing "it" only once
by Roy Johnson (Monsignor) on Sep 21, 2005 at 17:24 UTC
    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.
      Roy Johnson,
      Wow - thanks! That's neat, but I am not sure if it fits the bill. If my understanding of this is correct, it basically ignores subsequent matches if a match has already been found. If that is technically accurate, it fails in that it still checks to see if there is a match before deciding to ignore it.

      This really is a meditation about being able to modify the optree (or the p6 equivalent) while the code is running and what you would do with it if you could. I provided the example of removing a conditional block once the condition has been met and the block ran once. This means not even the condition itself is checked, it would just be "gone". This, I am sure, is not the only application.

      Cheers - L~R

        This code illustrates that the op only performs the match once:
        my $type; my $r = qr/(?{print "$type\n"})/; for (1..3) { $type = 'Regular'; /$r/; $type = 'Once only'; ?$r?; }
        On the broader subject of modifying the optree...well, it hasn't really occurred to me very often. The most common reason to do it is to introduce new syntax, which I guess is what you're suggesting, after a fashion. If I were up to it, I would probably want to implement a new operator.

        (update: But there's more to adding syntax than modifying the optree. It's gotta parse, too.)


        Caution: Contents may have been coded under pressure.
Re^5: Doing "it" only once
by Anonymous Monk on Sep 22, 2005 at 08:22 UTC
    my %things = (foo => sub {print "skipping foo\n"; next}, bar => sub {handle_bar($_); next}, ); for (@some_array) { (delete $things{$_})->() if exists $things{$_}; handle_rest($_); }
      Anonymous Monk,
      But that doesn't quite fit the bill. That is the equivalent of keeping it as if statements. Since the value is known to only exist one time the body will only ever be ran once but you still check for it every single time. The difference here is instead of checking the fetching a value and comparing it you are checking for the existance of a key. The point is to make the check and the attached block of code completely go away.

      Cheers - L~R