はちゅにっき

こっちのブログはまったり更新

Non Moose/Mouse なモジュールを継承して Moose/Mouse なモジュールにしたい (第二版)

Moose / Mouse を利用していないクラスを継承して、Moose / Mouse を利用した新しいクラスを作りたい
http://d.hatena.ne.jp/magicalhat/20090417/1239943579

という記事に対して

Mouseでの非Moose/Mouseクラスの継承法
http://blog.eorzea.asia/2009/07/post_15.html

というトラックバックをいただきました。
しかもさらっと書いた質問にまで答えていただき、ありがとうございます><

で、トラックバック先の記事にも書いてあるように、先日書いた記事の方法だと Mouse の環境下では正しく継承が利用できません。
自分が試したときは、Any::Moose で Mouse ではなく Moose がロードされていたため、うまく動いてたようです。
ということをすぐに日記に書けばよかったんだけど><


というわけで、最近の解決法は

package Foo;

use Any::Moose;
extends 'DateTime';
no Any::Moose;

__PACKAGE__->meta->make_immutable(inline_constructor => 0);

sub bar
{
    my $self = shift;
    return 'ばーぼん'.$self->ymd.'はうす';
}

1;

"inline_constructor => 0" がミソらしいです。
こうやって書いておくと

use strict;
use warnings;
use feature qw( say );

use Foo;
use Data::Dumper;

say Foo->now, "\n"; # => 現在時刻がかえってくるよ

my $foo = Foo->new(
    year  => 2009,
    month => 7,
    day   => 9,
);

say Dumper $foo->meta; # => Mouse がかえって。。。きてるよね?
say $foo->ymd; # => 2009-07-09
say $foo->bar;  # => ばーぼん2009-07-09はうす

というふうに、Moose でも Mouse でも期待する動作をしてくれます。たぶん。
うん、たぶん。やっぱり確証はないんだけれど。。。
"inline_constructor" ってゆーのは、 Mouse/Meta/Class.pm あたりをみると

sub make_immutable {
    my $self = shift;
    my %args = (
        inline_constructor => 1,
        inline_destructor  => 1,
        @_,
    );

    my $name = $self->name;
    $self->{is_immutable}++;

    if ($args{inline_constructor}) {
        $self->add_method('new' => Mouse::Meta::Method::Constructor->generate_constructor_method_inline( $self ));
    }

    if ($args{inline_destructor}) {
        $self->add_method('DESTROY' => Mouse::Meta::Method::Destructor->generate_destructor_method_inline( $self ));
    }

    return 1;
}

となっていて、どうやら inline_constructor に 1 を与えて*1 make_immutable を呼び出すと、Mouse::Meta::Method::Constructor がコードを生成し eval 使ってコンストラクタをよしなにしてくれるようです。
ほんと?
デストラクタも同様に生成してくれるようですね。
でも、ちょっとこの辺はしっかり調べるなりしないとダメですね。
ごめんなさい。


最近、仕事では PHP ばかり、というか PHP オンリーの拷問の日々のため、おうちに帰ってきたときくらいしか Perl を使う機会がありません。
そして、おうち帰ってくると、プログラム書くより寝たいというか。
本当はダメなんですが。。。
そんなわけで Twitter

Perl 初心者が傷をなめあう IRC とかあればいいのに

ってつぶやいたら、id:foosin さんから

@magicalhat つ 言いだしっぺの法則

って返ってきました。
IRC の使い方とかまだ全然分かってないんだけど「それもありかな?」と思ったりもします。
もしくはなんか、そーゆー場を作ってみたいというか。
ruby-list の ML に加入していますが、活発に情報が交換されていて、ちょっと羨ましいというか。。。


「最近 Perl もだいぶ上達したし、そろそろベストプラクティスって言われている Plagger でも読んでみるか」
と思い、読んでみたら Plagger.pm から先がなかなか読めなくて泣きそう。


「エベレスト登っているつもりだったのに、気づいたら天保山の中腹だった!」


くらいの次元のコミュニティでもいいので。
それでもまだまだ学びたいと思う、それが自分にとっての一番の Perl の魅力ですね。

*1:とゆーかデフォルトで 1 が渡る