Mouseの挙動が不可解なように思う件 → 解決


(10/19追記)ここで述べている問題は、Data::Util 0.53にて修正されました。同じ現象が発生した場合はData::Utilのバージョンを上げてください。

(10/21さらに追記)と思ったらaroundで落ちる現象を確認。実はこれPerlコアのバグだったらしい。対策は可能らしいので、id:gfx先生のバージョンアップにご期待ください。

(10/27追記)遅ればせながら、Data::Util 0.54でbefore, after, aroundともに動作することを確認しました。

CPAN最新版のMouse0.39で確認。

use strict;
use warnings;

package Person;
use Mouse;

sub chk {}

around chk => sub {
    eval "use Hoge";
    if ( $@ ) {
        warn 'failed';
    } else {
        warn 'succeeded';
    }
    warn 'return';
};

package main;
my $p = Person->new;
$p->chk;
warn 'exit';

この場合、「failed」「return」「exit」と表示されると思いきや、「failed」「return」だけで「exit」が表示されない。

use Mouseをuse Mooseにすると「exit」まで表示されるので、Mouse特有の事情と思われます。まだMouseのコード見てないので、aroundだけで起こる現象なのかとか、原因は不明。ちなみに、MooseCPAN最新(0.92)で確認。

(10/18追記)MouseのメソッドモディファイアはClass::Method::Modifiers::Fastが使われていて、どうやらそこの問題っぽい。Class::Method::Modifiersだとexitまで表示されるけど、Fastだとbefore, after, aroundともにexitが出ない。もう少し見てみる。

Class::Method::Modifiers::Fastも実際のメソッド書き換えはやってなくて、それを担当してるのがData::Util。Data::Utilは基本XSで実装されてて、$ENV{DATA_UTIL_PUREPERL}に値が入ってるとPurePerl実装が動くようになってる。Data::Util::PurePerlだと上記のサンプルは「exit」まで表示されるので、XSの実装がネックっぽい。XSのパッチは書けないのでレポート上げてみよう。


(10/19追記)冒頭にも書いたように、Data::Util 0.53でこの問題は修正されました。