Moose::Util::TypeConstraintsによるアクセサのタイプ制限について
Xbrlの格闘から、ようやくコーディングができる状態までやってきた。
色々となにがいいか調査をしている間に、perlのMooseというモジュールにたどりつき、
試しに色々と使ってみようかと考えているところである。
さっそく、Moose::Util::TypeConstraintsを利用して、アトリビュートにオブジェクトタイプの制約を設定してみた。
作成したモジュールは下記のとおり。
package Car;
use warnings;
use strict;
use Carp;
use version; our $VERSION = qv('0.0.3');
use Moose;
use Moose::Util::TypeConstraints;
has 'name' => ( is => 'rw', isa => 'Str');
has 'type' => ( is => 'rw', isa => 'Str');
subtype 'Tire'
=> as 'Object'
=> where { $_->isa('Tire') };
has 'tire' => ( is => 'rw', isa => 'Tire' );
package Tire;
use warnings;
use strict;
use Carp;
use version; our $VERSION = qv('0.0.3');
# Module implementation here
use Moose;
has 'size' => ( is => 'rw', isa => 'Int' );
has 'width' => ( is => 'rw', isa => 'Int' );
has 'profile' => ( is => 'rw', isa => 'Int' );
これらのモジュールを下記のようなテストスクリプトから呼び出し。
use Test::More tests => 2;
use Car;
use Tire;
my $new_tire = Tire->new(
size => 285,
inch => 20,
profile => 35
);
my $new_car = Car->new(
name => 'GT-R'
);
$new_car->tire('YOKOHAMA');
$new_car->tire($new_tire);
$new_car->type('sports');
is( $new_car->name, 'GT-R', 'getter name');
is( $new_car->type, 'sports', 'getter sports');
モジュールのテストを実施すると、下記のような2つのエラーが発生
①Prototype mismatch: sub Car::type ($$;$$) vs none at /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/Class/MOP/Package.pm line 94.
②Attribute (tire) does not pass the type constraint because: Validation failed for 'Tire' failed with value YOKOHAMA at (eval 74) line 7
Car::tire('Car=HASH(0xa12a7c0)', 'YOKOHAMA') called at t/01.cat.t line 14
②のほうは、tireアトリビュートの制約エラーなのでこちらの想定したとおりなってOK。
①のほうはCARオブジェクトのtypeメソッドではなく、useしているMoose::Util::TypeConstraints
パッケージのtypeメソッドが呼ばれていて、プロトタイプエラーになっている模様。
Carモジュールの下記のように修正
1. use Moose::Util::TypeConstraintsに()をつけてメソッドのインポートを抑制
2. subtype,as,whereをパッケージ修飾子をつけて指定
package Car;
use warnings;
use strict;
use Carp;
use version; our $VERSION = qv('0.0.3');
use Moose;
use Moose::Util::TypeConstraints();
has 'name' => ( is => 'rw', isa => 'Str' );
has 'type' => ( is => 'rw', isa => 'Str' );
Moose::Util::TypeConstraints::subtype 'Tire'
=> Moose::Util::TypeConstraints::as 'Object'
=> Moose::Util::TypeConstraints::where { $_->isa('Tire') };
has 'tire' => ( is => 'rw', isa => 'Tire' );
わざわざ、パッケージ修飾子つけるのも面倒なので、Mooseによるアクセサの作成のされ方等、
ソースを調べてみないとわからないかもしれないが、他に方法がないか引き続き調査中。
どう考えても、Moose::Util::TypeConstraintsのメソッド名と自分で作成するメソッド名が
重複する可能性は高いので、何かしらの簡潔な解決方法を見つけないといけないかもしれない。
Perlベストプラクティス (2006/08/24) Damian Conway 商品詳細を見る |
実用Perlプログラミング (2006/03) サイモン カズンズ 商品詳細を見る |