使用Try :: Tiny还是Eval?

ado*_*ado 8 perl

哪个更安全,更好,更清洁,更推荐使用?

我用了:

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");
}
Run Code Online (Sandbox Code Playgroud)

但对于这种情况(参见错误部分),我被告知使用Try :: Tiny更好吗?

我的问题是:你会怎么写这个,为什么你会这样选择?

Bor*_*din 13

更新

感谢匿名用户,我已经能够纠正我的答案中的错误.所述returncatch块不具有所需效果,因为它从返回的唯一的catch子例程.

如果没有异常,则try返回try块的值,否则返回块的值catch.所以这个版本正确执行并返回$c->redirect("/index")if 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($_);
  };
}
Run Code Online (Sandbox Code Playgroud)

Try::Tiny非常重要,因为错误处理eval在一般情况下确实很难实现.该模块的文档说明了这一点

这个模块提供了基本的try/catch/finally语句,旨在最大限度地减少eval块的常见错误,以及NOTHING else.

该模块的主要重点是为那些仍然想要编写正确的eval块的人提供简单而可靠的错误处理,每次没有5行样板.

你的代码看起来像这样

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");
}
Run Code Online (Sandbox Code Playgroud)

我希望你会同意的更好.

有两点值得注意:

  • trycatch子程序编码看起来像语言的话.这意味着最后一个闭合支撑后的分号是必不可少的.

  • 出于同样的原因,returntrycatch块内将无法按预期工作,并将简单地退出块,返回到父子例程.请参阅上面的更新.

  • catch块内$@具有其原始值之前try.错误产生的值是$_