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 {...}
?
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.
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.
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.
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.
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 };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With