UNIVERSAL::isa($hoge, 'Huga') を使うべきではない

ことの理由と出典をいつも忘れてしまうので,メモメモ。

if ($obj->isa('Huga')) {
    ......
}

みたいなコードはよく使うんですが,$obj が bless されたオブジェクト(か,クラス名の文字列スカラー)じゃないとエラーを吐くので,一時期,以下のように書いてました。

if (UNIVERSAL::isa($obj, 'Huga')) {
    ......
}

でもそれはイカーン,とどこかで読んだような気がして探してたら,「続・初めてのPerl 改訂版」の「14.2 オブジェクトの動作に関するテスト(pp.186-188)」に書いてありました。

しかし,これではオブジェクト指向カニズムを否定することになり,それはそれで問題を起こします(→脚注)。

脚注
特に,Animal がカスタムの isa メソッドを持つ場合(中略),UNIVERSAL::isa を呼び出してしまうと,Animal::isa を無視してしまいますから,間違った答えが返ってくる場合があります。

いつもそうだよねそうだよね,でも独自 isa をインプリメントするモジュールなんてそんなにないべ,とか考えて頭をすぐスルーしてしまうんでなかなか覚えられないのでした。

どうすべきかというと,単に eval で囲うだけ

if (eval { $obj->isa('Hoge') } ) {
    ......
}

うす,日記に書いたからもう忘れないメソッド。

これくらいだと正当な引用に入りますよね……後ろめたいので,この例以外にもお役立ちな原典へのアサマしくないリンクを張っておきます。タイトルにだまされがちですが,中級者なら一度は読んでおくべき本だと思います。ページ数に比してちょっとお高めだけど。

続・初めてのPerl 改訂版

続・初めてのPerl 改訂版