日向夏特殊応援部隊

俺様向けメモ

Params::Coerce のメモ

Params::Coerce の使い方が良く分からなかったので試してみました。

追記 (2008-06-09T18:22:10+09:00)

と言うか、すぐに間違えに気づいたので内容を大幅に書き換え(ぉぃ

Params::Coerce とは

特定のクラスのインスタンスから違うクラスのインスタンスへ変換する枠組みを提供するモジュールです。

coerce の使い方

変換元に __as_Dest_Class メソッドを定義する方法

例えば Path::Class::File オブジェクトURI オブジェクトに変換したいって場合に次のような書き方が出来ます。

package Path::Class::File;

use URI;

sub __as_URI {
    my $self = shift;
    URI->new('file://' . $self->absolute);
}

package main;

use Data::Dump qw(dump);
use Params::Coerce qw();
use Path::Class qw();
use Perl6::Say;

my $file = Path::Class::file('.', 'test.pl');
my $uri = Params::Coerce::coerce('URI', $file);

say dump $uri;

変換元のオブジェクト、つまりここでは Path::Class::File に __as_Class_Name と言ったメソッドを定義しておくと、Class::Name 型のオブジェクトへの変換ルールを定義出来て、この型変換部は、Params::Coerce::coerce()関数で上手い事ディスパッチしてくれるみたいです。

変換先に __from_Src_Class メソッドを定義する方法

Path::Class::File -> URI への変換の際に、先ほどは Path::Class::File にメソッドを生やして定義したけど、逆に変換先のクラスである URIメソッドを生やす方式でも変換可能です。

package URI;

use URI;
use Params::Coerce qw(from);

sub __from_Path_Class_File {
    my ($self, $file) = @_;
    URI->new('file://' . $file->absolute);
}

package main;

use Data::Dump qw(dump);
use Path::Class qw();
use Perl6::Say;

my $file = Path::Class::file('.', 'test.pl');
my $uri = Params::Coerce::coerce('URI', $file);

say dump $uri;

使う側からすれば、Path::Class::Fileに(__as_Dest_Class)変換ルールがあろうとも、URIに(__from_Src_Class)変換ルールがあろうとも coerce で指定した変換先のクラス名を指定しておけば変換可能です。

URI 専用の coerce を作りたい

前の例とほとんど変わらない。

package Path::Class::File;

use URI;

sub __as_URI {
    my $self = shift;
    URI->new('file://' . $self->absolute);
}

package main;

use Data::Dump qw(dump);
# use Params::Coerce qw();
use Params::Coerce '_URI' => 'URI';
use Path::Class qw();
use Perl6::Say;

my $file = Path::Class::file('.', 'test.pl');
# my $uri = Params::Coerce::coerce('URI', $file);
my $uri = _URI($file);

say dump $uri;

コメントアウトの直後が改変点。結果は同じになる。
これは当たり前だけど、__from_Path_Class_File を URI に定義したケースでも同じ結果になる。

from の使い方

変換先クラスに変換用のディスパッチメソッドとなるfromを生やす方法です。

package URI;

use URI;
use Params::Coerce qw(from);

sub __from_Path_Class_File {
    my ($self, $file) = @_;
    URI->new('file://' . $file->absolute);
}

package main;

use Data::Dump qw(dump);
use Path::Class qw();
use Perl6::Say;

my $file = Path::Class::file('.', 'test.pl');
my $uri = URI->from($file);

say dump $uri;

URI->from で対応している変換を行う事が出来ます。

まとめ

Params::Coerce を使うとオブジェクトの変換ルールを上手い事定義出来る枠組みが出来る。

  • 基本的には変換元に __as_Target_Class
  • または変換先に __from_Src_Class

と言ったメソッドのいずれかを定義しておくと、Params::Coerce::coerce() によってシームレスなオブジェクト型変換を行う事が出来る。

また特定のオブジェクトへの変換だけを制御するメソッドを定義出来る。(例だと _URI メソッド)
さらに変換先クラスにて変換元オブジェクトを受け付けるディスパッチメソッドとして from を import する事が出来る。