モダンPerlの世界へようこそ

第4回 Any::Moose:なにがどうでもムースはムース

この記事を読むのに必要な時間:およそ 5 分

アクセサ生成に特化したMouse

ただ,実際にこのようなことまで意識しながらMooseを使っている人はかなりの少数派。一般的には最初の例のように,アトリビュートの部分のみMooseで書いて,メソッドはMooseの機能を使わず,従来のやり方でクラスにベタ書きしてしまうことがほとんどです。

もちろんそれがいけないというわけではありませんし,このように既存のオブジェクトに簡単に組み込めるところがMooseの利点でもあるのですが,Mooseをアクセサ生成モジュールとしてしか使わないのであれば,わざわざこれほど大量のメタオブジェクトを生成する必要はありません。同じようなAPIを提供するにしても,もっと軽くて速い方法があるはずです。

そのような認識のもとで登場したのが,ショーン・ムーア(Shawn M. Moore)氏のMouseでした(2008年6月⁠⁠。

この当時のMouseは本当に機能が限られていて,hasによるアクセサ生成とextendsによる継承くらいしか対応していなかったのですが,メーリングリスト上の報告を鵜呑みにするなら,同じテストをMooseで実行した場合に比べて3分の1ほどの実行時間で済んだというのですからなかなかの高速化ぶりです。

どのくらい変わったかを見るために,先ほどのサンプルに少々手を加えてダンプしてみましょう。

package MouseObj;
use Mouse;
has 'name' => (is => 'rw', isa => 'Str', default => 'foo');
sub print { my $self = shift; print $self->name; }

package main;
use Data::Dumper;
local $Data::Dumper::Indent = 1;
print Dumper(MouseObj->new->meta);

100行近くにもなったMooseのメタオブジェクトに比べて,Mouseのメタオブジェクトはたったのこれだけ。

$VAR1 = bless( {
  'superclasses' => [
    'Mouse::Object'
  ],
  'name' => 'MouseObj',
  'attributes' => {
    'name' => bless( {
      'init_arg' => 'name',
      'name' => 'name',
      'class' => 'MouseObj',
      'default' => 'foo',
      'is' => 'rw',
      'type_constraint' => 'Str'
    }, 'Mouse::Meta::Attribute' )
  }
}, 'Mouse::Meta::Class' );

これならオブジェクトの生成が3倍速くなったというのもうなずけるところです。

牧歌的な世界

このようなコードベースの異なる機能限定版は,管理コストが上昇するためいやがられることもありますが,さいわい,Mouseの場合は,Mooseの作者スティーヴン・リトル氏からも好意的に迎えられました。

その年のYAPC::AsiaでMooseの発表を行ったnothingmuchことユーヴァル・コグマン(Yuval Kogman)氏からは,⁠気に入ったから使いたいけれど,あとから文句が出るといけないから」という理由で,コードをいじらなくてもMooseとMouseを切り替えられるようにする(ロード時にすでにMooseがロードされていたらMooseとして振る舞い,MooseがいなければMouseを呼び出してMouseとして振る舞う)Squirrel(リス)というモジュールを贈られています。

SquirrelのPODには「Moose(ヘラジカ)とSquirrel(リス)は大の仲良し。でも,Mooseがいないのであれば,SquirrelはMouse(ネズミ)とも楽しくやれるよ」という記述が見られるのですが,この一文が暗示するように,この頃のMooseの世界は,さまざまな動物が仲良く暮らしている,実に牧歌的な世界でした。

シカ事変

ところが,2008年も後半になると,その牧歌的な世界にいささかぎすぎすした空気が流れるようになってきます。ユーヴァル・コグマン氏が危惧していたように,Mooseを大事にしすぎるあまり,⁠あとから文句が出る」ようになったためです。

同年9月にリリースされたゼバスティアン・リーデル(Sebastian Riedel)氏のMojoに対する攻撃については以前別の特集記事でちらと紹介しましたが,同年春に開催されたYAPC::Asia以降Mooseベースに切り替わっていたHTTP::Engineも,11月に開催されたHTTP::Engine ConferenceやShibuya Perl Mongersのテクニカルトークからの流れで,高速化のためにMooseをやめ,同じようなインタフェースを持つShika(鹿)という国産モジュールを採用した途端に,一部のMoose開発陣から強い非難を寄せられました※2⁠。

※2

このあたりの経緯は当事者である松野徳大・大沢和宏両氏による日本語のまとめ記事が存在しています。リアルタイムで読まれた方も多いと思いますが,未読の方はあわせてご覧ください。

このときは,YAPC::Asiaの常連であり,ムーア氏の上司にもあたるジェシー・ヴィンセント(Jesse Vincent)氏らの取りなしもあって,Shikaのかわりに,すでに軽量化モジュールとして名前が知られていたMouseを使うことで決着がついたのですが,もともとカジュアルな用途で使うことしか想定していなかった当時のMouseは,バリバリのMooseベースで書かれていたHTTP::Engineをサポートするにはあまりに力不足でした。

そこで,HTTP::Engineチームが,Shikaで得られた知見を活かしながら,Mouseにどんどん機能を追加していった結果――もともとMouseは,できないことがあればMooseに切り替えればよい,という割り切ったスタンスでつくられていたのですが――いまではよほど高度なメタオブジェクト操作を行うのでもない限り,Mouseひとつで事足りてしまうようになりました(細かなところで本家と整合性がとれていない箇所は残っていますが,日常的に使うレベルではわざわざMooseを呼ぶ必要を感じないくらい完成度も互換性も高いものに仕上がっています⁠⁠。

著者プロフィール

石垣憲一(いしがきけんいち)

あるときは翻訳家。あるときはPerlプログラマ。先日『カクテルホントのうんちく話』(柴田書店)を上梓。最新刊は『ガリア戦記』(平凡社ライブラリー)。

URLhttp://d.hatena.ne.jp/charsbar/