Muddy structured types

I would like to create a structured type in Moose that can be used as a type for another Moose attribute. For example, I would like to create an attribute namethat has its own attributes valueand error.

Therefore, I would like to know the best way to achieve this. I created a working example by specifying a simple Moose class to represent a shared object Field. It has attributes valueand error. Then I created another Moose class for the object Person. It has attributes idand name, both of which are of type Field:

Define a common field object:

package MyApp::Type::Field;
use Moose;
use namespace::autoclean;

has 'value' => ( is => 'rw' );  
has 'error' => ( is => 'rw', isa => 'Str' );

__PACKAGE__->meta->make_immutable;
1;

Define a Person object that uses the field object:

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;

Do something with the Person object:

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 value error name id MyApp::Type::Field .

, , , Person : $person->id( MyApp::Type::Field->new() );, id.

, ?

+2
2

default ?

has 'id' => (
    is => 'rw',
    isa => 'MyApp::Type::Field',
    default => sub { MyApp::Type::Field->new }
);

... BUILD.

+1

:

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::Type::Field', coerce => 1 );
    
+1

All Articles