web-dev-qa-db-fra.com

Quel est le meilleur moyen de gérer les exceptions en Perl?

J'ai remarqué que Exception.pm et Error.pm ne semblent pas être largement utilisés dans la communauté Perl. Est-ce dû à la grande empreinte de eval pour la gestion des exceptions?

De plus, les programmes Perl semblent avoir une politique beaucoup plus souple en ce qui concerne la gestion des exceptions en général. Y a-t-il une raison impérieuse à cela?

En tout état de cause, quelle serait la meilleure méthode de traitement des exceptions en Perl?

25
ennuikiller

Le consensus de la communauté Perl semble être que Try :: Tiny est la méthode préférée pour gérer les exceptions. La "politique d'indulgence" à laquelle vous faites référence est probablement due à une combinaison de:

  • Perl n'étant pas un langage entièrement orienté objet. (Par exemple, contrairement à Java où vous ne pouvez pas éviter de traiter avec des exceptions.)
  • Le fond de nombreux développeurs Perl. (Langues comme C1 et Shell n’ont pas mécanismes d’exception.)
  • Le type de tâches que les utilisateurs ont tendance à utiliser pour Perl. (Petits scripts pour la synthèse de texte et la génération de rapports Lorsque la gestion des exceptions n'est pas nécessaire.)
  • Perl ne disposant pas d'un (bon) mécanisme d'exception intégré.

Notez que le dernier élément signifie que vous verrez beaucoup de code comme ceci:

eval { something() };
if ($@) {
    warn "Oh no! [$@]\n";
}

C'est la gestion des exceptions même s'il n'utilise pas la syntaxe try/catch. Cependant, il est fragile et résoudra un certain nombre de cas Edge subtils auxquels la plupart des gens ne pensent pas. Try :: Tiny et les autres modules de traitement des exceptions sur CPAN ont été écrits pour faciliter la tâche.

1. C a setjmp() et longjmp(), qui peuvent être utilisés pour une forme très grossière de traitement des exceptions.

49
Michael Carman

Ne testez jamais $ @ tel quel, car il s'agit d'une variable globale. Même le test lui-même peut le modifier.

Modèle général d'évaluation:

my $result;

eval {
    $result= something();
    # ...
    1;  # ok
} or do {
    my $eval_error= $@ || "error";
    # ...
    die $eval_error;
};  # needs a semicolon

En pratique, c'est le moyen le plus léger. Cela laisse encore une infime marge de manœuvre pour le comportement drôle des $ @, mais rien qui me préoccupe suffisamment.

0
user10922431