++ed by:

1 PAUSE user

Moritz Onken


 package Address;
 use Moose;
 use MooseX::Attribute::Dependent;

 has street => ( is => 'rw', dependency => All['city', 'zip'] );
 has city => ( is => 'ro' );
 has zip => ( is => 'ro', clearer => 'clear_zip' );

 no MooseX::Attribute::Dependent;

 Address->new( street => '10 Downing Street' );
 # throws error
 Address->new( street => '10 Downing Street', city => 'London' );
 # throws error
 Address->new( street => '10 Downing Street', city => 'London', zip => 'SW1A 2AA' );
 # succeeds
 my $address = Address->new;
 $address->street('10 Downing Street');
 # throws error
 $address->zip('SW1A 2AA');
 $address->street('10 Downing Street');
 # succeeds


Moose type constraints restrict based on the value of the attribute. Using this module, attributes can have more complex constraints, which involve values of other attributes. It comes with a few constraints and can easily be extended.



All related attributes must have a value.


At least one related attribute must have a value.


None of the related attributes can have a value.


At least one of the related attributes cannot have a value.


To define your own dependency, first create a class to register your custom dependency. In this example, we want to restrict an attribute to values smaller than serveral other attributes.

 package MyApp::Types;
 use MooseX::Attribute::Dependency;
 use List::MoreUtils ();
        name               => 'SmallerThan',
        message            => 'The value must be smaller than %s',
        constraint         => sub {
            my ($attr_name, $params, @related) = @_;
            return List::MoreUtils::all { $params->{$attr_name} < $params->{$_} } @related;

Then load MyApp::Types in your class before loading MooseX::Attribute::Dependent and set the dependency on an attribute.

 package MyClass;
 use Moose;
 use MyApp::Types;
 use MooseX::Attribute::Dependent;

 has small => ( is => 'rw', dependency => SmallerThan['large'] );
 has large => ( is => 'rw' );
 MyClass->new( small => 10, large => 1); # dies
 MyClass->new( small => 1, large => 10); # lives

When creating your own dependency it is important to know that there is a difference in the parameters passed to the contraint function. If the object is in the process of being created (e.g. MyClass->new(...)) the second parameter is a hashref and consists of the parameters passed to new (actually the return value of BUILDARGS). If the accessor of an attribute with dependency is called to set a value (e.g. $object->small(10)), the second parameter is the object itself ($object).