开发者

Is there a cleaner way to conditionally 'last' out of this Perl loop?

开发者 https://www.devze.com 2023-04-02 23:42 出处:网络
Not really knowing Perl, I have been enhancing a Perl script with help from a friendly search engine.

Not really knowing Perl, I have been enhancing a Perl script with help from a friendly search engine.

I find that I need to break out of a loop while setting a flag if a condition comes true:

foreach my $element (@array) {
    if($costlyCondition) {
        $flag = 1;
        last;
    }
}

I know that the nicer way to use 'last' is something like this:

foreach my $element (@array) {
    last if ($costlyCondition);
}

Of course, this means that while I can enjoy the syntactic sugar, I cannot set my flag inside开发者_Go百科 the loop, which means I need to evaluate $costlyCondition once again outside.

Is there a cleaner way to do this?


you can use a do {...} block:

do {$flag = 1; last} if $costlyCondition

you can use the , operator to join the statements:

$flag = 1, last if $costlyCondition;

you can do the same with the logical && operator:

(($flag = 1) && last) if $costlyCondition;

or even the lower priority and:

(($flag = 1) and last) if $costlyCondition;

at the end of the day, there's no real reason to do any of these. They all do exactly the same as your original code. If your original code works and is legible, leave it like it is.


I agree with Nathan, that while neat looking code is neat, sometimes a readable version is better. Just for the hell of it, though, here's a horrible version:

last if $flag = $costly_condition;

Note the use of assignment = instead of equality ==. The assignment will return whatever value is in $costly_condition.

This of course will not make $flag = 1, but whatever $costly_condition is. But, since that needs to be true, so will $flag. To remedy that, you can - as Zaid mentioned in the comments - use:

last if $flag = !! $costly_condition;

As mentioned, pretty horrible solutions, but they do work.


One thought is to do the loop in a subroutine that returns different values depending on the exit point.

my $flag = check_elements(\@array);

# later...

sub check_elements {
  my $arrayref = shift;
  for my $ele (@$arrayref) {
    return 1 if $costly_condition;
  }
  return 0;
}


This is possible, but highly not recommended: such tricks decrease readability of your code.

foreach my $element (@array) {
    $flag = 1 and last if $costlyCondition;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消