綾小路龍之介の素人思考

[perl] Net::Twitter で例外ハンドリング

本家のPodを少しだけ改良。正しくevalしなくちゃだめ。あとrefチェック入れた。

Net::Twitter本家のPodに書かれている例外チェックを使って上手くチェックできずにはまっていたので。本家のpodに書かれている例外チェックの基本はモジュールで用意されている関数を呼ぶ場合はevalで囲んでevalの外で$@をチェック。いちいちevalするのめんどくさいんじゃということで、下のような感じにしていた。

my $statuses = $nt->friends_timeline(); # this might die!
if ( $@ ) {
    # friends_timeline encountered an error

    if ( blessed $@ && $@->isa('Net::Twitter::Error') ) {
        #... use the thrown error obj
        warn $@->error;
    }
    else {
        # something bad happened!
        die $@;
    }
}

まぁ当然ながらこれだと、evalしてないので、evalのエラーメッセージを格納する特殊変数$@をチェックしてもしょうがない(多分)。friend_timelineの中でdieした場合にはスクリプト自体が終了する。ということで、正しくevalしませう。

eval {
    my $statuses = $nt->friends_timeline(); # this might die!
};
if ( $@ ) {
    # friends_timeline encountered an error

    if ( blessed $@ && $@->isa('Net::Twitter::Error') ) {
        #... use the thrown error obj
        warn $@->error;
    }
    else {
        # something bad happened!
        die $@;
    }
}

例えば、friends_timeline以前にeval内でdieが呼ばれる可能性がある場合、$@はどのような形かわからない。つまり、blessされいるか、Net::Twitter::Errorのblessか、という2点のチェックでは不十分な場合がある。そこで、$@のチェックにリファレンスかどうかのチェックを追加する。

use Scalar::Util qw/blessed/;
eval {
    open my $fp, "<hoge.txt" or die "$!";
    close $fp;
    my $statuses = $nt->friends_timeline(); # this might die!
};
if ( $@ ) {
    # friends_timeline encountered an error

    if ( !ref $obj || blessed $@ && $@->isa('Net::Twitter::Error') ) {
        #... use the thrown error obj
        warn $@->error;
    }
    else {
        # something bad happened!
        die $@;
    }
}

本当ならdieする可能性があるならそのつど例外ハンドリングしたほうがいいかも。あと、evalって子プロセスを走らせるんだっけ?誰か教えてくれ。

リファレンス

  1. Can't locate object method "blessed" perl - Google 検索
  2. ファイルハンドルをめぐる冒険(ただしマニア向け) - daily dayflower
  3. blessed perl - Google 検索
  4. blessされたオブジェクトか、クラス名の文字列 - Unknown::Programming
  5. Net::Twitter - search.cpan.org
  6. perl eval プロセス - Google 検索
  7. perl die - Google 検索

ソーシャルブックマーク

  1. はてなブックマーク
  2. Google Bookmarks
  3. del.icio.us

ChangeLog

  1. Posted: 2009-01-07T08:03:55+09:00
  2. Modified: 2009-01-07T08:03:55+09:00
  3. Generated: 2016-11-14T23:09:29+09:00