use strict; use warnings; use feature 'say', 'state'; use Types::Standard 'Undef'; use Types::Common::String 'SimpleStr','StrLength'; use Type::Params 'compile'; state $check = compile ( Undef | (SimpleStr & (StrLength[1,4]))->plus_coercions( SimpleStr, sub { warn 'coercing'; length ? $_ : undef }, ) ); #no warnings 'uninitialized'; for my $str ( undef, '', 'abcd', 'abcde' ) { my $label = ! defined($str) ? 'undef' : ! length ($str) ? 'empty' : $str; my $checked = $check->($str); say sprintf('%s : >%s<', $label, $str); } #### Use of uninitialized value in sprintf at 11130005.pl line 20. undef : >< coercing at 11130005.pl line 10. empty : >< abcd : >abcd< coercing at 11130005.pl line 10. Value "abcde" did not pass type constraint "Undef|__ANON__" (in $_[0]) at 11130005.pl line 18 "Undef|__ANON__" requires that the value pass "Undef" or "__ANON__" Value "abcde" did not pass type constraint "Undef" Value "abcde" did not pass type constraint "Undef" "Undef" is defined as: (!defined($_)) Value "abcde" did not pass type constraint "__ANON__" is a subtype of "SimpleStr&StrLength[1,4]" "SimpleStr&StrLength[1,4]" requires that the value pass "SimpleStr" and "StrLength[1,4]" Value "abcde" did not pass type constraint "StrLength[1,4]" "StrLength[1,4]" expects length($_) to be between 1 and 4 length($_) is 5