Проблема
Многие используют Try::Tiny. Все в этом модуле хорошо, только не хватает вот чего-то вроде:
try { die Class1->new(); } catch('Class1') { # Catch all exceptions of Class1 } catch('Class2') { # Catch all exceptions of Class2 } catch { # Catch other exceptions }К сожалению, сделать такой синтаксис, не убрав "::Tiny" с названия модуля, не так просто. Кроме того, переписывать Try::Tiny вообще нет никакого желания.
Решение 1
Немного подумав я пришел к такому варианту:try { die Class1->new(); } catch { when ('Class1') { # Catch all exceptions of Class1 } when ('Class2') { # Catch all exceptions of Class1 } default { # Catch other exceptions } }Чтобы такой синтаксис заработал необходимо перегрузить "~~" ("Smart match") для ваших объектов исключений. Вот пример реализации
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Exception::Base; | |
use overload | |
'~~' => sub { $_[0]->isa( $_[1] ) }, | |
fallback => 1; | |
package Exception1; | |
use base 'Exception::Base'; | |
sub new { bless {}, shift } | |
package Exception2; | |
use base 'Exception::Base'; | |
sub new { bless {}, shift } | |
package Exception3; | |
use base 'Exception::Base'; | |
sub new { bless {}, shift } | |
package main; | |
use Try::Tiny; | |
use v5.10; | |
test_exception( Exception1->new() ); | |
test_exception( Exception2->new() ); | |
test_exception( Exception3->new() ); | |
test_exception("Special text\n"); | |
test_exception("Text exception\n"); | |
sub test_exception { | |
my $e = shift; | |
try { | |
die $e; | |
} | |
catch { | |
when ('Exception1') { | |
say ref($_) . " matches Exception1"; | |
} | |
when ('Exception2') { | |
say ref($_) . " matches Exception2"; | |
} | |
when ('Exception::Base') { | |
say ref($_) . " matches Exception::Base"; | |
} | |
when (/Special/) { | |
chomp; | |
say qq{"$_" matches qr/Special/}; | |
} | |
default { | |
chomp; | |
say qq{"$_" matches default}; | |
} | |
}; | |
} |
Решение 2
Если нет возможности перегрузить "~~", то можно пойти другим путем, добавить некий хелпер, например "e"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ... | |
test_exception( Exception1->new() ); | |
test_exception( Exception2->new() ); | |
test_exception( Exception3->new() ); | |
test_exception("Special text\n"); | |
test_exception("Text exception\n"); | |
use Scalar::Util qw/blessed/; | |
sub e($) { | |
my $class = shift; | |
my $e = $_; | |
return unless blessed($e); | |
return $e->isa($class); | |
} | |
sub test_exception { | |
my $e = shift; | |
try { | |
die $e; | |
} | |
catch { | |
when ( e 'Exception1') { | |
say ref($_) . " matches Exception1"; | |
} | |
when ( e 'Exception2' ) { | |
say ref($_) . " matches Exception2"; | |
} | |
when ( e 'Exception::Base' ) { | |
say ref($_) . " matches Exception::Base"; | |
} | |
when (/Special/) { | |
chomp; | |
say qq{"$_" matches qr/Special/}; | |
} | |
default { | |
chomp; | |
say qq{"$_" matches default}; | |
} | |
}; | |
} |
0 коммент.:
Отправить комментарий
Не забудьте добавить себя в постоянные читатели и включить уведомления о новых комментариях, либо воспользуйтесь RSS каналом ;)