$ perl -Moose -e'has a=>(is=>"rw",isa=>"Undef",coerce=>1); __PACKAGE__->new(a=>"abc")' Attribute (a) does not pass the type constraint because: Validation failed for 'Undef' failed with value abc at [snip backtrace] $ perl -Moose -e'has a=>(is=>"rw",isa=>"Undef|Undef",coerce=>1); __PACKAGE__->new(a=>"abc")' $ perl -Moose -e'has a=>(is=>"rw",isa=>"Undef|Undef",coerce=>0); __PACKAGE__->new(a=>"abc")' Attribute (a) does not pass the type constraint because: Validation failed for 'Undef|Undef' failed with value abc at [snip backtrace] #### BEGIN { package Class; use strict; use warnings; use Moose; has val => ( is => 'rw', isa => 'Num', required => 1, ); use Moose::Util::TypeConstraints; coerce __PACKAGE__ => from 'Num' => via { __PACKAGE__->new(val => $_) }; } BEGIN { package Container; use strict; use warnings; use Moose; has always => ( is => 'rw', isa => 'Class', coerce => 1, default => sub { Class->new(val => 0) }, ); has union => ( is => 'rw', isa => 'Undef|Class', coerce => 1, default => undef, ); } use strict; use warnings; use Test::More tests => 30; use Scalar::Util qw( blessed ); sub ta { $_[0] && blessed($_[0]->always) && blessed($_[0]->always) eq 'Class' } sub tu { $_[0] && ( !$_[0]->union || blessed($_[0]->union) && blessed($_[0]->union) eq 'Class' ) } my $always_fail = qr/^Attribute \(always\) does not pass the type constraint/; my $union_fail = qr/^Attribute \(union\) does not pass the type constraint/; my $o = Class->new(val => 123); my $c; $c = eval { Container->new() }; is($@, ''); ok(ta($c)); $c = eval { Container->new(always => $o) }; is($@, ''); ok(ta($c)); $c = eval { Container->new(always => 123) }; is($@, ''); ok(ta($c)); $c = eval { Container->new(always => "abc") }; like($@, $always_fail); ok(!$c); $c = eval { Container->new(union => undef) }; is($@, ''); ok(tu($c)); $c = eval { Container->new(union => $o) }; is($@, ''); ok(tu($c)); $c = eval { Container->new(union => 123) }; is($@, ''); ok(tu($c)); $c = eval { Container->new(union => "abc") }; like($@, $union_fail); ok(!$c); $c = Container->new(); eval { $c->always($o) }; is($@, ''); ok(tu($c)); eval { $c->always(123) }; is($@, ''); ok(tu($c)); eval { $c->always("abc") }; like($@, $always_fail); ok(tu($c)); eval { $c->union(undef) }; is($@, ''); ok(tu($c)); eval { $c->union($o) }; is($@, ''); ok(tu($c)); eval { $c->union(123) }; is($@, ''); ok(tu($c)); eval { $c->union("abc") }; like($@, $union_fail); ok(tu($c)); #### $ perl a.pl 1..30 ok 1 ok 2 ok 3 ok 4 ok 5 ok 6 ok 7 ok 8 ok 9 ok 10 ok 11 ok 12 ok 13 ok 14 not ok 15 # Failed test at a.pl line 71. # '' # doesn't match '(?-xism:^Attribute \(union\) does not pass the type constraint)' not ok 16 # Failed test at a.pl line 71. ok 17 ok 18 ok 19 ok 20 ok 21 ok 22 ok 23 ok 24 ok 25 ok 26 ok 27 ok 28 not ok 29 # Failed test at a.pl line 82. # '' # doesn't match '(?-xism:^Attribute \(union\) does not pass the type constraint)' ok 30 # Looks like you failed 3 tests of 30.