if ($TYPE{$name} && $TYPE_SOURCE{$name} ne $pkg) {
Carp::croak "The type constraint '$name' has already been created in $TYPE_SOURCE{$name} and cannot be created again in $pkg";
};
- my $constraint = $conf{where} || do { $TYPE{delete $conf{as} || 'Any' } };
+ my $constraint = $conf{where} || do {
+ my $as = delete $conf{as} || 'Any';
+ if (! exists $TYPE{$as}) { # Perhaps it's a parameterized source?
+ Mouse::Meta::Attribute::_build_type_constraint($as);
+ }
+ $TYPE{$as};
+ };
my $as = $conf{as} || '';
$TYPE_SOURCE{$name} = $pkg;
Carp::croak "A coercion action already exists for '$type'"
if $COERCE{$name}->{$type};
- Carp::croak "Could not find the type constraint ($type) to coerce from"
- unless $TYPE{$type};
+ if (! $TYPE{$type}) {
+ # looks parameterized
+ if ($type =~ /^[^\[]+\[.+\]$/) {
+ Mouse::Meta::Attribute::_build_type_constraint($type);
+ } else {
+ Carp::croak "Could not find the type constraint ($type) to coerce from"
+ }
+ }
push @{ $COERCE_KEYS{$name} }, $type;
$COERCE{$name}->{$type} = $code;
#!/usr/bin/env perl
use strict;
use warnings;
-use Test::More tests => 7;
+use Test::More tests => 9;
use Test::Exception;
{
} qr/Attribute \(complex\) does not pass the type constraint because: Validation failed for 'ArrayRef\[HashRef\[Int\]\]' failed with value/, "Bad args for complex types throws an exception";
}
+{
+ {
+ package Bar;
+ use Mouse;
+ use Mouse::Util::TypeConstraints;
+
+ subtype 'Bar::List'
+ => as 'ArrayRef[HashRef]'
+ ;
+ coerce 'Bar::List'
+ => from 'ArrayRef[Str]'
+ => via {
+ [ map { +{ $_ => 1 } } @$_ ]
+ }
+ ;
+ has 'list' => (
+ is => 'ro',
+ isa => 'Bar::List',
+ coerce => 1,
+ );
+ }
+
+ lives_and {
+ my @list = ( {a => 1}, {b => 1}, {c => 1} );
+ my $bar = Bar->new(list => [ qw(a b c) ]);
+
+ is_deeply( $bar->list, \@list, "list is as expected");
+ } "coercion works";
+
+ throws_ok {
+ Bar->new(list => [ { 1 => 2 }, 2, 3 ]);
+ } qr/Attribute \(list\) does not pass the type constraint because: Validation failed for 'Bar::List' failed with value/, "Bad coercion parameter throws an error";
+}
+