http://qs321.pair.com?node_id=11115640


in reply to Perl Best Practices - Loop Labels

Another contrived and incomplete example:

# Validate a data set ITEM: foreach my $item (@data) { foreach my $key (qw(foo bar baz)) { if (!exists $item->{$key}) { warn "Couldn't grok item. $key missing. Skipping.\n", Dump +er($item); next ITEM; } } # Do something useful with this item. }

A perfectly sane approach. Of course the inner loop could have been a grep, and you could warn after the grep if the number of matching keys doesn't reach the expectation:

if (3 != grep {exists $item->{$_}} qw(foo bar baz)) { warn ....; # but your warning can't be as specific. next; }

But either way you're dealing with nested loops, just in different forms. Sometimes the use-case doesn't lend itself well to a grep or map, and sometimes, even, there's advantage to bailing out at the earliest opportunity. And sometimes not bailing out early makes it harder to keep track of what condition led to the need to bail out at all.

My suggestion is this: If labels make a particular section of code easier to understand, and jumping out of nested depths is the appropriate thing to do, don't let a Perl Critic policy dissuade you. Just be sure that you really have chosen the clearest code expression that can solve the problem at the appropriate level of efficiency. If you make your code more complex in an effort to avoid jumping out of a nested loop, everyone loses. If you make it more complex by jumping out, everyone loses. If there is a better construct that avoids the issue entirely, use it. If there is not, use the construct that achieves the needs, but with code clarity high on the list of needs. This will mean sometimes jumping out of a nested loop, or skipping to the next outer iteration is the right thing to do.


Dave