Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Restrict attributes based on values of other attributes

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 lib
Octocat-spinner-32 t
Octocat-spinner-32 .gitignore
Octocat-spinner-32 Changes
Octocat-spinner-32 README.pod
Octocat-spinner-32 dist.ini
README.pod

SYNOPSIS

 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->city('London');
 $address->zip('SW1A 2AA');
 $address->street('10 Downing Street');
 # succeeds

DESCRIPTION

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.

AVAILABLE DEPENDENCIES

All

All related attributes must have a value.

Any

At least one related attribute must have a value.

None

None of the related attributes can have a value.

NotAll

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

CUSTOM DEPENDENCIES

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 ();
 
 MooseX::Attribute::Dependency::register({
        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).

Something went wrong with that request. Please try again.