Поиск…


eval и die

Это встроенный способ справиться с «исключениями», не полагаясь на сторонние библиотеки, такие как Try :: Tiny .

my $ret;

eval {
  $ret = some_function_that_might_die();
  1;
} or do {
  my $eval_error = $@ || "Zombie error!";
  handle_error($eval_error);
};

# use $ret

Мы «злоупотребляем» тем фактом, что die имеет ложное возвращаемое значение, а возвращаемое значение общего кодового блока - это значение последнего выражения в кодовом блоке:

  • если $ret назначено успешно, то 1; выражение - последнее, что происходит в блоке eval code. Таким образом, блок кода eval имеет истинное значение, поэтому блок or do блок не запускается.
  • если some_function_that_might_die() действительно die , то последнее, что происходит в блоке eval code, является die . Таким образом, блок eval кода имеет ложное значение, и блок or do блок выполняет его.
  • Первое, что вы должны сделать в блоке or do блоке, - читать $@ . Эта глобальная переменная будет содержать любой аргумент, который передается die . || "Zombie Error" популярен, но не нужен в общем случае.

Это важно понять, потому что некоторые не все коды не срабатывают, вызывая die, но та же структура может использоваться независимо. Рассмотрим функцию базы данных, которая возвращает:

  • количество строк, повлиявших на успех
  • '0 but true' если запрос успешный, но ни одна строка не была затронута
  • 0 если запрос не был успешным.

В этом случае вы все равно можете использовать ту же идиому, но вам нужно пропустить последний 1; , И эта функция должна быть последней вещью в Eval. Что-то вроде этого:

eval {
  my $value = My::Database::retrieve($my_thing); # dies on fail
  $value->set_status("Completed");
  $value->set_completed_timestamp(time());
  $value->update(); # returns false value on fail
} or do { # handles both the die and the 0 return value
  my $eval_error = $@ || "Zombie error!";
  handle_error($eval_error);
};


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow