By default, all attributes in MooX::Struct are read-only, but it's easy to make them read-write...
use MooX::Struct -rw, Person => [qw( $name @addresses )];
For your members example, Moose's native traits would probably be helpful. Moo doesn't currently offer anything similar to this, but there is somebody developing such a beast - I believe it will be on CPAN soonish. I'd probably do something along these lines...
use v5.14;
package Person {
use Moose;
use overload q[""] => sub { $_[0]->name }, fallback => 1;
has name => (
is => 'ro',
isa => 'Str',
required => 1,
);
}
package Club {
use Moose;
use overload q[""] => sub { $_[0]->name }, fallback => 1;
has name => (
is => 'ro',
isa => 'Str',
required => 1,
);
# This is a private attribute. We want people to only
# manipulate the member list via add_members, etc.
has _members => (
traits => ['Array'],
is => 'ro',
isa => 'ArrayRef[Person]',
init_arg => undef,
default => sub { [] },
handles => {
add_members => 'push',
has_members => 'count',
list_members => 'elements',
_uniq_members => 'uniq',
},
);
# ensure uniqueness
after add_members => sub {
my $self = shift;
@{ $self->_members } = $self->_uniq_members;
};
}
my $club = Club->new(name => "The Breakfast Club");
$club->add_members(
Person->new(name => "Allison"),
Person->new(name => "Andy"),
Person->new(name => "Brian"),
Person->new(name => "Brian"), # duplicate
);
$club->add_members(
Person->new(name => "Andy"), # duplicate
Person->new(name => "Claire"),
Person->new(name => "John"),
);
say for $club->list_members;
package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
|