Recherche…


eval et mourir

C'est la manière intégrée de gérer les "exceptions" sans avoir recours à des bibliothèques tierces comme 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

Nous "abusons" du fait que die a une valeur de retour fausse, et la valeur de retour du bloc de code global est la valeur de la dernière expression dans le bloc de code:

  • si $ret est assigné avec succès, alors le 1; expression est la dernière chose qui se produit dans le bloc de code eval . Le bloc de code eval a donc une valeur vraie, donc le bloc or do ne s'exécute pas.
  • Si some_function_that_might_die() die , la dernière chose qui se passe dans le bloc de code eval est le die . Le bloc de code eval a donc une valeur fausse et le bloc or do est exécuté.
  • La première chose que vous devez faire dans le or do bloc est lu $@ pour . Cette variable globale contiendra tout argument passé pour die . Le || "Zombie Error" guard est populaire, mais inutile dans le cas général.

Ceci est important à comprendre car certains appels au dé ne font pas échouer tous les codes, mais la même structure peut être utilisée indépendamment. Considérons une fonction de base de données qui renvoie:

  • le nombre de lignes affectées par le succès
  • '0 but true' si la requête est réussie mais qu'aucune ligne n'a été affectée
  • 0 si la requête a échoué.

Dans ce cas, vous pouvez toujours utiliser le même idiome, mais vous devez ignorer le dernier 1; , et cette fonction doit être la dernière chose dans l'éval. Quelque chose comme ça:

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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow