Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl do...while and last command

Tags:

perl

I've just encountered some very weird behavior that I really can't explain:

do {
    my $qry = $self->getHTMLQuery(undef, $mech->content());
    next if (!defined($qry));

    push(
        @prods,
        map { 'http://www.XXXXYYYX.com'.$_->attr('href') }
            $qry->query('div.prodInfo div.prodInfoBox a.prodLink.GridItemLink')
    );

    $qry->delete();
    $TEST++;

    last if ($TEST >= 10);

} while(eval { $mech->follow_link(class => 'jump next') });

print "WHILE ENDED\n";

The code above never prints "WHILE ENDED" even though it does seem to go out of the while loop when $TEST >= 10.

But the following code does print "WHILE ENDED":

do {
    my $qry = $self->getHTMLQuery(undef, $mech->content());
    next if (!defined($qry));

    push(
        @prods,
        map { 'http://www.XXXXYYYX.com'.$_->attr('href') }
            $qry->query('div.prodInfo div.prodInfoBox a.prodLink.GridItemLink')
    );

    $qry->delete();
    $TEST++;

} while(eval { $mech->follow_link(class => 'jump next') } && $TEST <= 10);

print "WHILE ENDED\n";

In both tests, the initial value of $TEST is 0.

Is the behavior of last in do...while different than in for and while {...}?

like image 758
snoofkin Avatar asked Oct 25 '11 23:10

snoofkin


People also ask

What is last command in Perl?

The last keyword is a loop-control statement that immediately causes the current iteration of a loop to become the last. No further statements are executed, and the loop ends. If LABEL is specified, then it drops out of the loop identified by LABEL instead of the currently enclosing loop.

Do While statements Perl?

In practice, you use the do... while loop statement when you want the loop executes at least one before the condition is checked. When you enter the by string in the command line, the condition in the do while statement becomes false that terminates the loop.

What is do command in Perl?

Description. This function when supplied a block, do executes as if BLOCK were a function, returning the value of the last statement evaluated in the block. When supplied with EXPR, do executes the file specified by EXPR as if it were another Perl script.

How do I break a nested loop in Perl?

Perl last Statement with LABEL Using the Perl last statement alone, you can exits only innermost loop. If you want to exit a nested loop, put a label in the outer loop and pass label to the last statement.


1 Answers

A do block with a looping modifier doesn't count as a real loop as far as next, last, and redo are concerned. This is mentioned in perlsyn, where you'll find the tip Schwern mentioned about surrounding it with a bare block to make last work. But that won't work with next, because a bare block is only executed once, so next acts like last. To make next work, you can put the bare block inside the do, but then last will act like next.

If you need both next and last to work with a do ... while, the easiest way is to use an infinite loop with the real condition in a continue block. These 2 loops are equivalent, except that the second is a real loop, so it works with next & last:

do { ... } while condition;
while (1) { ... } continue { last unless condition };
like image 58
cjm Avatar answered Oct 28 '22 04:10

cjm