X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMooseX%2FMeta%2FTypeConstraint%2FStructured%2FNamed.pm;h=bcbc9962fdac1876dd3856082e450b7651484ede;hb=67be6b65eafdcc510a27f502aaad8070dc0674b3;hp=837cf3476254aa114c41d60b340ea8007985f92b;hpb=bc5c0758d92c58286c4ba66a613850492525d752;p=gitmo%2FMooseX-Types-Structured.git diff --git a/lib/MooseX/Meta/TypeConstraint/Structured/Named.pm b/lib/MooseX/Meta/TypeConstraint/Structured/Named.pm index 837cf34..bcbc996 100644 --- a/lib/MooseX/Meta/TypeConstraint/Structured/Named.pm +++ b/lib/MooseX/Meta/TypeConstraint/Structured/Named.pm @@ -2,7 +2,6 @@ package MooseX::Meta::TypeConstraint::Structured::Named; use Moose; use Moose::Meta::TypeConstraint (); -use Moose::Util::TypeConstraints; extends 'Moose::Meta::TypeConstraint'; with 'MooseX::Meta::TypeConstraint::Role::Structured'; @@ -11,41 +10,34 @@ with 'MooseX::Meta::TypeConstraint::Role::Structured'; MooseX::Meta::TypeConstraint::Structured::Named - Structured Type Constraints -=head1 VERSION +=head1 SYNOPSIS -0.01 +The follow is example usage: -=cut - -our $VERSION = '0.01'; + use Moose::Util::TypeConstraints; + use MooseX::Meta::TypeConstraint::Structured::Named; + + my %required = (key1='Str', key2=>'Int'); + my %optional = (key3=>'Object'); + + my $tc = MooseX::Meta::TypeConstraint::Structured::Named->new( + name => 'Dict', + parent => find_type_constraint('HashRef'), + package_defined_in => __PACKAGE__, + signature => {map { + $_ => find_type_constraint($required{$_}); + } keys %required}, + optional_signature => {map { + $_ => find_type_constraint($optional{$_}); + } keys %optional}, + ); =head1 DESCRIPTION -Structured type constraints let you assign an internal pattern of type -constraints to a 'container' constraint. The goal is to make it easier to -declare constraints like "ArrayRef[Int, Int, Str]" where the constraint is an -ArrayRef of three elements and the internal constraint on the three is Int, Int -and Str. - -To accomplish this, we add an attribute to the base L -to hold a L, which is a reference to a pattern of type constraints. -We then override L to check our incoming value to the attribute -against this signature pattern. - Named structured Constraints expect the internal constraints to be in keys or -fields similar to what we expect in a HashRef. - -=head1 TYPES - -The following types are defined in this class. - -=head2 Moose::Meta::TypeConstraint - -Used to make sure we can properly validate incoming signatures. - -=cut - -class_type 'Moose::Meta::TypeConstraint'; +fields similar to what we expect in a HashRef. Basically, this allows you to +easily add type constraint checks against values in the wrapping HashRef +identified by the key name. =head1 ATTRIBUTES @@ -58,9 +50,7 @@ contraint container. =cut -has '+signature' => ( - isa=>'HashRef[Moose::Meta::TypeConstraint]', -); +has '+signature' => (isa=>'HashRef[Moose::Meta::TypeConstraint]'); =head2 optional_signature @@ -69,11 +59,7 @@ contraint container. These are optional constraints. =cut -has 'optional_signature' => ( - is=>'ro', - isa=>'HashRef[Moose::Meta::TypeConstraint]', - predicate=>'has_optional_signature', -); +has '+optional_signature' => (isa=>'HashRef[Moose::Meta::TypeConstraint]'); =head1 METHODS @@ -109,22 +95,26 @@ sub constraint { my $self = shift; return sub { my %args = $self->_normalize_args(shift); - my @signature = keys %{$self->signature}; - my @ptional_signature = keys %{$self->optional_signature} - if $self->has_optional_signature; + my @optional_signature; + + if($signature[-1]->isa('MooseX::Meta::TypeConstraint::Structured::Optional')) { + my $optional = pop @signature; + @optional_signature = @{$optional->signature}; + } ## First make sure all the required type constraints match - while( my $type_constraint_key = shift @signature) { - my $type_constraint = $self->signature->{$type_constraint_key}; - if(my $error = $type_constraint->validate($args{$type_constraint_key})) { + foreach my $sig_key (keys %{$self->signature}) { + my $type_constraint = $self->signature->{$sig_key}; + if(my $error = $type_constraint->validate($args{$sig_key})) { confess $error; + } else { + delete $args{$sig_key}; } - delete $args{$type_constraint_key}; } ## Now test the option type constraints. - while( my $arg_key = keys %args) { - my $optional_type_constraint = $self->signature->{$arg_key}; + foreach my $arg_key (keys %args) { + my $optional_type_constraint = $self->optional_signature->{$arg_key}; if(my $error = $optional_type_constraint->validate($args{$arg_key})) { confess $error; } @@ -161,27 +151,7 @@ sub signature_equals { return 1; } -=head2 equals - -modifier to make sure equals descends into the L -=cut - -around 'equals' => sub { - my ($equals, $self, $compared_type_constraint) = @_; - - ## Make sure we are comparing typeconstraints of the same base class - return unless $compared_type_constraint->isa(__PACKAGE__); - - ## Make sure the base equals is also good - return unless $self->$equals($compared_type_constraint); - - ## Make sure the signatures match - return unless $self->signature_equals($compared_type_constraint); - - ## If we get this far, the two are equal - return 1; -}; =head1 AUTHOR