10

次のコード (簡略化された例、実際にはオブジェクトのリストを繰り返し処理し、例外をトラップしようとしています) は、for リストの次の項目に移動してエラー処理を実行します。これは機能しますが、catch サブルーチン内でループ制御ステートメントを使用すると警告が表示されます。

use strict;
use warnings;
use Try::Tiny;
use 5.010;

NUM: for my $num (1 .. 10) { 
  try { 
    if ($num == 7) { 
      die 'ugly number'; 
    } 
  } catch { 
    chomp;
    say qq/got "$_"/; 
    next NUM; 
  }; 
  say qq/number $num/; 
}

出力:

number 1
number 2
number 3
number 4
number 5
number 6
got "ugly number at testtry.pl line 9."
Exiting subroutine via next at testtry.pl line 14.
Exiting subroutine via next at testtry.pl line 14.
number 8
number 9
number 10

これを回避する方法は 2 つあります。この使用法の範囲内で、範囲指定された警告なしブロックを使用して警告を閉じるか、エラー メッセージを一時変数にコピーして、catch ブロックの外側で /next をチェックします。前者には私が見落としている問題がある可能性があり、2 番目にはエラー処理が少し広がります。どちらが優先されますか、または私が見落としている別の方法はありますか?

4

4 に答える 4

7

catch ブロック内にno warnings 'exiting'. これにより、警告が無効になります。strictプラグマとプラグマはあなたwarningsを助けるためにあります。邪魔になったらレキシカルに自由に無効にしてください。

このperldiagページには、組み込みの警告とエラーのカテゴリが一覧表示されます。このカテゴリを無効にすることで消音されるすべてのメッセージを確認し、その価値があるかどうかを判断できます。

編集:

成功すると がtry返されることを利用できますが、エラーの場合はブロックundefの値を取得します。catchこれにより、次のことが可能になります。

NUM: for my $num (1 .. 10) { 
  try {
    die 'ugly number' if $num == 7;
  } catch { 
    chomp;
    say qq/got "$_"/; 
    return 1;       # return some true value
  } and next NUM;   # go to next iteration here, outside the try/catch
  say qq/number $num/; 
}

ただし、no warnings解決策はよりエレガントで、はるかに明白であることがわかりました。

于 2013-05-21T14:14:06.830 に答える
2

このケースの適切な解決策 (そしておそらく解決しようとしているより一般的なケースの場合) はtry、明示的なループ制御に依存するのではなく、エラーがない場合にのみ発生するはずのものをブロックに入れることです。それは次のようになります。

for my $num (1 .. 10) { 
  try { 
    if ($num == 7) { 
      die 'ugly number'; 
    } 
    say qq/number $num/; 
  } catch { 
    chomp;
    say qq/got "$_"/;
  }; 
}

lastは、ループ本体を単純にスキップする以上のことを行う必要があるため、実際には少し注意が必要なループ制御ステートメントです。しかし、考慮してください

try {
  for my $num (1 .. 10) { 
    try {
      die 'ugly number' if $num == 7;
      die 'early exit' if $num == 9;
      say qq/number $num/; 
    } catch {
      die $_ if /^early exit/;
      chomp;
      say qq/got "$_"/;
    }; 
  }
};
于 2013-05-21T19:31:29.950 に答える
0

別の回避策は、おそらくこの単純化された例にのみ有用であり、プログラム全体では有用ではありませんが、次のnextように、ダイの後にコードを配置する命令を避けることです。

use strict;
use warnings;
use Try::Tiny;
use 5.010;

for my $num (1 .. 10) { 
  try { 
    if ($num == 7) { 
      die 'ugly number'; 
    }   
    say qq/number $num/; 
  } catch { 
    chomp;
    say qq/got "$_"/; 
    #next NUM; 
  }; 
  #say qq/number $num/; 
}

次の結果が得られます。

number 1
number 2
number 3
number 4
number 5
number 6
got "ugly number at script.pl line 11."
number 8
number 9
number 10
于 2013-05-21T13:55:31.877 に答える