8

より安全で、より良く、よりクリーンで、より推奨される使用方法はどれですか?

私が使用した:

sub insert_exec {
    my ($self, $c, $args) = @_;
    my ($params, $table, $model) = $self->_init({context => $c, args => $args});
    eval {  $model->insert($table, $params);
    };
    if ($@) {  return $c->show_error($@);  } ## error
    $c->redirect("/index");
}

しかし、このような場合 (エラーの部分を参照) には、Try::Tiny を使用した方がよいと言われました。

私の質問は次のとおりです。これをどのように書き、なぜその方法を選択するのですか?

4

3 に答える 3

14

アップデート

匿名ユーザーのおかげで、回答のバグを修正できました。returnブロック内のは、サブルーチンcatchからのみ返されるため、目的の効果がありませんでした。catch

例外がなかった場合はブロックtryの値を返しtry、それ以外の場合はブロックの値を返しますcatch。したがって、このバージョンは正しく実行され、 が成功した$c->redirect("/index")場合はの値を返し、それ以外の場合は を呼び出して の値を返します。insert$c->show_error($_)

sub insert_exec {
  my ($self, $c, $args) = @_;
  my ($params, $table, $model) = $self->_init({context => $c, args => $args});
  try {
    $model->insert($table, $params);
    $c->redirect("/index");
  }
  catch {
    $c->show_error($_);
  };
}
  

Try::Tiny一般的なケースでエラー処理をeval正しく行うのは非常に難しいため、これは非常に重要です。モジュールのドキュメントにはこう書かれています

このモジュールは、eval ブロッ​​クでよくある間違いを最小限に抑えるように設計された、最低限の try/catch/finally ステートメントを提供します。

このモジュールの主な焦点は、毎回 5 行のボイラープレートなしで正しい eval ブロッ​​クを書きたいと考えている人のために、シンプルで信頼性の高いエラー処理を提供することです。

あなたのコードは次のようになります

use Try::Tiny;

sub insert_exec {
  my ($self, $c, $args) = @_;
  my ($params, $table, $model) = $self->_init({context => $c, args => $args});
  try {
    $model->insert($table, $params);
  }
  catch {
    return $c->show_error($_);
  };
  $c->redirect("/index");
}

あなたが同意することを願っています。

注目すべき点は次の 2 つです。

  • try言語の単語のように見えるようにコード化されたcatchサブルーチンです。つまり、最後の右中括弧の後のセミコロンは必須です。

  • 同じ理由で、 orブロックreturn内では期待どおりに動作せず、単純にブロックを終了して親サブルーチンに戻ります。上記の私の更新を参照してください。trycatch

  • catchブロック内には、 の$@前の元の値がありtryます。エラーの結果の値は$_

于 2013-08-02T09:48:40.220 に答える
4

使用しないTry::Tinyと、追加の依存関係が節約されます。

これを使用すると、Perl のイディオムの知識がなくても理解できるコードを作成できます (業界全体でより一般的に認識されている用語に置き換えることにより)。

それらの相対的な価値を客観的に測定することは難しいため、どちらが自分にとってより価値があるかを判断する必要があります。

于 2013-08-02T09:36:07.947 に答える