【发布时间】:2023-04-04 07:51:01
【问题描述】:
我想在 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 中,我希望能够直接访问该人的name 和id 的value 和error 属性,而无需先实例化一个新的MyApp::Type::Field 对象每个人的属性。
或者,换句话说,如果Person 类的用户不必这样做:$person->id( MyApp::Type::Field->new() ); 在能够使用id 属性之前,我更喜欢它。
有没有一种干净的方法可以实现这一目标?
【问题讨论】: