77 votes

Try :: Tiny est-il toujours recommandé pour la gestion des exceptions dans Perl 5.14 ou version ultérieure?

Le consensus de la communauté Perl semble être qu' Try::Tiny est la meilleure façon de gérer les exceptions.

Perl 5.14 (qui est la version que j'utilise) semble résoudre les problèmes avec eval que Try::Tiny adresses. Va Try::Tiny encore fournir des avantages pour moi?

34voto

brian d foy Points 71781

Ma réponse est impopulaire, mais je ne pense pas que les programmeurs Perl devrait être d'essayer d'utiliser les extrêmement pauvres notion de la chose que nous appelons des "exceptions" en Perl. Il s'agit essentiellement d'un canal latéral de la valeur de retour. Cependant, tout en étant séduit par l'idée d'exceptions, même avec toutes les complexités de l'utilisation d'une variable globale pour le passer autour de l'état, les gens continuer à essayer de faire le travail.

En pratique, cependant, les gens utilisent des die pour signaler l'échec. Certains diront que vous pouvez die avec une référence et passer de nouveau objets d'erreur, mais vous n'avez pas besoin d' die . Nous avons des objets, de sorte que nous devrions utiliser toute la puissance des objets:

 sub some_sub {
    ...
    return Result->new( error => 1, description => ... ) if $something_went_wrong;
    return Result->new( error => 0, ... );
    }

 my $result = some_sub( ... );
 if( $result->is_error ) { ... };

Qui n'implique pas de variables globales, l'action à distance, la portée des maux de tête, ou exigent des promotions. Vous créer une petite classe Result, ou ce que vous voulez l'appeler, pour envelopper vos valeurs de retour de sorte que vous avez des données structurées au lieu de valeurs sans identité. Il n'y a pas plus à vous demander ce qu'est une valeur de retour signifie. C'est qu' undef d'une valeur réelle ou une indication de l'échec? Est la valeur de retour de la bonne si elle est définie ou si c'est vrai? Votre objet peut vous dire ces choses. Et, vous pouvez utiliser le même objet die. Si vous utilisez déjà l'objet avec die et en l'utilisant comme valeur de retour, il y a très peu de recommander toutes les autres choses que vous avez à faire à tolérer $@.

Je parle plus à ce sujet dans "Retour d'erreur objets au lieu de lancer des exceptions"

Cependant, je sais que vous ne pouvez pas aider à ce que les autres font, donc vous avez encore à faire semblant de Perl a des exceptions.

31voto

ikegami Points 133140

Il a toujours été une affaire de préférence personnelle. Préférez-vous

my $rv;
if (!eval { $rv = f(); 1 } ) {
   ...
}

ou

my $rv = try {
   f();
} catch {
   ...
};

Mais gardez à l'esprit ce dernier utilise anon sous-marins, de sorte qu'il mess avec return, ainsi qu' next et la comme. Essayez::Tiny du try-catch pourrait bien se retrouver bien plus compliqué à mesure que vous ajoutez des canaux de communication entre le bloc catch et à l'extérieur.

Le meilleur des cas (plus simple) scénario pour le retour sur la seule exception est si $rv est toujours vrai quand il n'y a pas d'exception. Il se présenterait comme suit:

my $rv;
if ($rv = eval { f() }) {
   ...
   return;
}

vs

my $rv = try {
   f();
} catch {
   ...
};

if (!$rv) {
   return;
}

C'est pourquoi je voudrais utiliser TryCatch au lieu d' Essayer::Tiny - je utiliser un tel module.

Le changement de Perl signifie simplement que vous pouvez faire if ($@) de nouveau. En d'autres termes,

my $rv;
if (!eval { $rv = f(); 1 } ) {
   ...
}

peut être écrit

my $rv = eval { f() };
if ($@) {
   ...
}

14voto

duskwuff Points 69245

Si rien d'autre, Try::Tiny est toujours un bon sucre syntaxique. Si vous voulez quelque chose d'un peu plus lourd, il y a aussi TryCatch , ce qui résout certains problèmes liés au fait que les clauses de Try::Tiny sont des sous-programmes (par exemple, que return ne quitte pas la fonction englobante).

11voto

MySZ Points 143

Try::Tiny est facile et léger. Trop facile. Nous avons eu deux problèmes:

  • anonyme subs - il y avait toujours des problèmes avec 'return' instruction à l'intérieur de
  • la capture de toujours et de tout

J'ai donc fait quelques modifications à l' Try::Tiny, qui nous aide. Maintenant, nous avons:

try sub {},
catch 'SomeException' => sub {},
catch [qw/Exception1 Exception2/] => sub {},
catch_all sub {};

Je sais, cette syntaxe est un peu exotique, mais grâce à manifeste"sub', nos programmeurs savons maintenant que 'return' instruction sort juste de gestionnaire d'exception, et nous avons toujours attraper cette exceptions que nous voulons attraper :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X