Moose-0.92 > Moose::Manual::MooseX

題名

Moose::Manual::MooseX - おすすめの拡張モジュール

MooseX?

Mooseを拡張したり変更するのは簡単です(だからこそMooseはこれほど強力なのです)。MOPのAPIを使えば、独自のやり方で処理を行ったり、新しい機能を追加したり、一般的なカスタマイズを行うこともできます。

ただし、独自の拡張モジュールを書く場合は、メタモデルをよく理解しておく必要があります。まずはMoose::Manual::MOPのドキュメントをご覧ください。Moose::Cookbookにもいくつか拡張のためのレシピがあります。

拡張モジュールの書き方を説明するのはこのマニュアルの範囲を超えますが、ありがたいことに、すでに多くの人が拡張モジュールを書いてCPANにあげてくれています。

このドキュメントは、その中から私たちがもっとも愛用しているいくつかのモジュールを取り上げます。

MooseX::AttributeHelpers

拡張モジュールをひとつしか見ないのであれば、これを見るべきです。これは、配列リファレンスやハッシュリファレンス、数、文字列といったPerlのネイティブなデータ型すべてに委譲に相当するものを用意します。

これを使うと、はるかにきれいで流れるようなAPIを作成できるようになります。

  package User;

  use Moose;
  use MooseX::AttributeHelpers;

  has '_orders' => (
      metaclass => 'Collection::Array',
      is        => 'ro',
      isa       => 'ArrayRef',
      default   => sub { [] },
      provides  => {
          push     => 'add_order',
          shift    => 'next_order',
          elements => 'orders',
      },
  );

ここでは配列リファレンスをそのままさらすかわりに、わかりやすい名前のついた使いやすいメソッドを3つ用意しました。

MooseX::StrictConstructor

Mooseは、デフォルトでは余計な引数があってもすべてクラスのコンストラクタに渡してしまいますが、MooseX::StrictConstructorをロードすると、コンストラクタが認識できない引数があったときはエラーが発生するようになります。

  package User;

  use Moose;
  use MooseX::StrictConstructor;

  has 'name';
  has 'email';

  User->new( name => 'Bob', emali => 'bob@example.com' );

MooseX::StrictConstructorを使うと、「emali」というタイポのせいで実行時エラーが発生します(素のMooseの場合、「emali」アトリビュートは黙って無視されます)。

MooseX::Params::Validate

MooseX::Method::SignaturesMooseX::Declareの未来には大きな期待を寄せていますが、いまは、はるかに見劣りのする(ただし、速くて簡単な)MooseX::Params::Validateの方をおすすめします。このモジュールを使うと、Mooseの型や型変換をあらゆるメソッドの引数に適用できます。

  package User;

  use Moose;
  use MooseX::Params::Validate;

  sub login {
      my $self = shift;
      my ($password)
          = validated_list( \@_, password => { isa => 'Str', required => 1 } );

      ...
  }

MooseX::Getopt

これはnew_with_optionsというメソッドをクラスに追加してくれるロールです。これはコマンドラインオプションを受け取ってアトリビュートに値を入れてくれるコンストラクタです。

これを使うとコマンドラインアプリケーション用のモジュールを書くのが非常に簡単になります。

  package App::Foo;

  use Moose;
  with 'MooseX::Getopt';

  has 'input' => (
      is       => 'ro',
      isa      => 'Str',
      required => 1
  );

  has 'output' => (
      is       => 'ro',
      isa      => 'Str',
      required => 1
  );

  sub run { ... }

実行したいスクリプトの方にはこう書いておきます。

  use App::Foo;

  App::Foo->new_with_options->run;

これで、コマンドラインからこんな風にスクリプトを実行できるようになります。

  foo@example> foo --input /path/to/input --output /path/to/output

MooseX::Singleton

正直にいうと、シングルトンを使うのはハックにすぎないことも多いのですが、たしかにこれは便利なハックです。MooseX::Singletonを使うとMooseのクラスをシングルトンにできます。

  package Config;

  use MooseX::Singleton; # instead of Moose

  has 'cache_dir' => ( ... );

こんなに簡単。

検討中の拡張モジュール

CPANには文字通り何ダースもの拡張モジュールがありますが、ここでは、便利に思う人もいるかもしれないけれど、まだお墨付きをあげられるほどではない拡張モジュールを紹介します。

MooseX::Declare

これはDevel::Declareを使って、PerlそのものをMooseベースのキーワードで拡張しようというものです。非常にクールな拡張モジュールですが、まだ新しい、実験段階のものです。

  class User {

      has 'name'  => ( ... );
      has 'email' => ( ... );

      method login (Str $password) { ... }
  }

MooseX::Types

この拡張モジュールを使うと、アプリケーション用の型ライブラリを作成しやすくなります。また、あらかじめ型の名前を宣言しておくことで、裸のワードとして利用できるようになります。

  use MooseX::Types -declare => ['PositiveInt'];
  use MooseX::Types::Moose 'Int';

  subtype PositiveInt
      => as Int,
      => where { $_ > 0 }
      => message {"Int is not larger than 0"};

ありがたいことにこの裸の名前はMooseの型レジストリの中では実は名前空間がついているので、アプリケーションによって型の定義が異なる場合でも、同じ裸の名前を使うことができます。

MooseX::Types::Structured

この拡張モジュールは、MooseX::Typesをベースに、複雑なデータ構造を持つ型を宣言できるようにします。

  use MooseX::Types -declare => [ qw( Name Color ) ];
  use MooseX::Types::Moose qw(Str Int);
  use MooseX::Types::Structured qw(Dict Tuple Optional);

  subtype Name
      => as Dict[ first => Str, middle => Optional[Str], last => Str ];

  subtype Color
      => as Tuple[ Int, Int, Int, Optional[Int] ];

もちろんオブジェクトを使えばいつでもこのようなことをすることはできます。

MooseX::ClassAttribute

この拡張モジュールは、Mooseのクラスにクラスアトリビュートを提供します。このモジュールを使って宣言したクラスアトリビュートは、通常のMooseのアトリビュートとまったく同じようにイントロスペクションできます。

  package User;

  use Moose;
  use MooseX::ClassAttribute;

  has 'name' => ( ... );

  class_has 'Cache' => ( ... );

MooseX::Daemonize

これは起動や停止、PIDファイルの管理、シグナル処理といった、デーモンを作成するときに便利なさまざまなメソッドを提供するロールです。

MooseX::Role::Parameterized

ロールを取り込む相手にあわせてカスタマイズしたい場合は、このツールがうってつけです。このモジュールを使うと、それぞれの相手にあわせてカスタマイズしたパラメータを受け取ってアトリビュートやメソッドなどを生成するロールを作成できます。

MooseX::POE

これはMooseのクラスとPOE::Sessionを結びつける小さなラッパです。また、eventというイベントハンドラを宣言するためのシュガー関数を提供しています。

MooseX::FollowPBP

『Perlベストプラクティス』風に、すべてのアクセサの名前を自動的に「get_size」や「set_size」のようにします。

MooseX::SemiAffordanceAccessor

すべてのアクセサの名前を自動的に「size」や「set_size」のように、getは明示せず、setは明示するようにします。

作者

Dave Rolsky <autarch@urth.org>

コピーライト & ライセンス

Copyright 2009 by Infinity Interactive, Inc.

http://www.iinteractive.com

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.