Perlで例外処理
とりあえず、手を動かして覚えることにした。
で、記事を書こうと思ったら、すでに良い感じの記事が存在するので、
それらを紹介しようと思う。
perl – use Carp; # warn() と die() だけじゃなくて – 404 Blog Not Found
http://blog.livedoor.jp/dankogai/archives/51073468.html
perlの例外処理のこと – cipher
http://ash.roova.jp/cipher/2013/08/perl-5182.html
という訳なので、Try::Lite
を使ってみようと思う。
詳しくは、以下をどうぞ。
Try::Lite 「より安全な例外キャッチを簡単に」 – YappoLogs
http://blog.yappo.jp/yappo/archives/000804.html
use strict; use warnings; use v5.10; use Try::Lite; my $file = 'not-exists.txt'; my $fp; try { open( $fp, '<', $file ) or die "Cannot open < $file. :$!"; } ( '*' => sub { say '--- for any exception ---'; say $@; } );
実行結果は、こんな感じ。
$ perl aaa.pl
--- for any exception ---
Cannot open < not-exists.txt. :No such file or directory at aaa.pl line 11.
こんな感じで、エラーをキャッチできる。
$!
がなんなのか分からなかったけど、
この辺を読んでなんとなく理解した。
perlvar – Perl で定義済みの変数 – perldoc.jp
http://perldoc.jp/docs/perl/5.16.1/perlvar.pod
なので、$!
はエラーが起きた直後に確保する必要がある。
そこで、任意のエラーメッセージと$!
を分けて確保する方法を考えてみる。
極端な例を上げるならこんな感じ。
use strict; use warnings; use v5.10; use Try::Lite; my $file = 'not-exists.txt'; my $fp; try { open( $fp, '<', $file ) or die [ "Cannot open < $file.", $! ]; } ( '*' => sub { say '--- for any exception ---'; say join "\n", @{$@}; } );
そして、結果はこんな感じ。
$ perl bbb.pl
--- for any exception ---
Cannot open < not-exists.txt.
No such file or directory
あと、このモジュールを使うとこういう風にも書ける。
package Exception; use strict; use warnings; sub new { my ( $pkg, $msg ) = @_; bless { msg => $msg }, $pkg; } package Foo; use strict; use warnings; use parent -norequire, 'Exception'; package main; use strict; use warnings; use v5.10; use Try::Lite; catch_test( Exception->new('This is Exception.') ); catch_test( Foo->new('This is Foo.') ); catch_test( 'This is string.' ); say '=== End of Script ==='; sub catch_test { my $ex = shift; try { die $ex; } ( 'Exception' => sub { say $@->{msg}; }, '*' => sub { say $@; } ); }
実行結果は、こんな感じ。
$ perl ccc.pl
This is Exception.
This is Foo.
This is string. at ccc.pl line 32.
=== End of Script ===
これだと、例外オブジェクトがFoo
の場合、
継承してるクラスを見て判断してくれるので、
'Foo' => sub { ... }
を用意する必要もないし、
bless
してない例外も捕捉できて便利。
おしまい。
Leave a Comment