我想在Moose中创建一个结构化类型,可以用作另一个Moose属性的类型。例如,我希望能够创建一个拥有自己的value和error属性的name属性。
因此,我想知道实现这一目标的最佳方法。我已经通过定义一个简单的Moose类来表示一个通用的Field对象,从而创建了一个工作示例。它具有value和error属性。然后,我为Person对象创建了另一个Moose类。它具有id和name属性,这两个属性的类型都是Field
定义一个通用字段对象:
package MyApp::Type::Field;
use Moose;
use namespace::autoclean;
has 'value' => ( is => 'rw' );
has 'error' => ( is => 'rw', isa => 'Str' );
__PACKAGE__->meta->make_immutable;
1;定义一个使用字段对象的Person对象:
package MyApp::Person;
use Moose;
use namespace::autoclean;
use MyApp::Type::Field;
has 'id' => ( is => 'rw', isa => 'MyApp::Type::Field' );
has 'name' => ( is => 'rw', isa => 'MyApp::Type::Field' );
__PACKAGE__->meta->make_immutable;
1;对Person对象执行一些操作:
package MyApp::Test;
use Moose;
use namespace::autoclean;
use MyApp::Person;
my $person = MyApp::Person->new();
# This works.
$person->id( MyApp::Type::Field->new() );
$person->id->value( 1 );
$person->id->error( 'Not found' );
# This fails as the name object has not yet been defined.
$person->name->value( 'Dave' );
# Can't call method "value" on an undefined value at ...
__PACKAGE__->meta->make_immutable;
1;这是可行的,但在MyApp::Test中,我希望能够直接访问person的name和id的value和error属性,而不必首先为person的每个属性实例化一个新的MyApp::Type::Field对象。
或者,换一种说法,我更希望Person类的用户在使用id属性之前不必执行以下操作:$person->id( MyApp::Type::Field->new() );。
有没有一种好的、干净的方法可以做到这一点?
发布于 2010-12-01 22:50:03
你也可以尝试强制:
coerce 'MyApp::Type::Field'
=> from 'Int'
=> via { MyApp::Type::Field->new( value => shift ) }
;这样一来,它只会:
$person->id( 1 );来设置它。尽管设置错误仍然需要按您所拥有的方式进行。
我可能应该提到,您需要执行以下操作:
Moose::Util::TypeConstraints添加到您放置coerce的包中。coerce标志添加到该字段:has id => ( is => 'rw',isa =>‘MyApp::=>::=>’,强制字段1 );
https://stackoverflow.com/questions/4324465
复制相似问题