Moose::Util::TypeConstraintsによるアクセサのタイプ制限について

Xbrlの格闘から、ようやくコーディングができる状態までやってきた。
色々となにがいいか調査をしている間に、perlMooseというモジュールにたどりつき、
試しに色々と使ってみようかと考えているところである。
さっそく、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ベストプラクティスPerlベストプラクティス
(2006/08/24)
Damian Conway

商品詳細を見る
実用Perlプログラミング実用Perlプログラミング
(2006/03)
サイモン カズンズ

商品詳細を見る