Skip Menu |

This queue is for tickets about the Type-Tiny CPAN distribution.

Report information
The Basics
Id: 98362
Status: resolved
Priority: 0/
Queue: Type-Tiny

People
Owner: perl [...] toby.ink
Requestors: DAKKAR [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in:
  • 0.047_05
  • 0.047_06
  • 0.047_07
  • 0.047_08
  • 0.047_09
  • 1.000000
  • 1.000001
  • 1.000002
Fixed in: (no value)



Subject: a Dict with optional values and custom coercions can fail to validate
If a Dict has some optional elements, and some non-optional ones, and some of them have non-inlineable coercions, it may randomly fail to validate. The issue is that C<is_strictly_a_type_of> will return either a true value, or the empty list. Since it's used in a C<map> to build the C<%is_optional> hash, that empty list messes up the hash. The attached patch provides a fix and a test case.
Subject: type-tiny-dict-optional-coerce.patch
diff --git i/lib/Types/Standard/Dict.pm w/lib/Types/Standard/Dict.pm index 8657fd3..4bec45f 100644 --- i/lib/Types/Standard/Dict.pm +++ w/lib/Types/Standard/Dict.pm @@ -247,8 +247,8 @@ sub __coercion_generator else { my %is_optional = map { - ; $_ => $dict{$_}->is_strictly_a_type_of($_optional) - } keys %dict; + ; $_ => !!$dict{$_}->is_strictly_a_type_of($_optional) + } sort keys %dict; $C->add_type_coercions( $parent => sub { my $value = @_ ? $_[0] : $_; diff --git i/t/20-unit/Types-Standard/deep-coercions.t w/t/20-unit/Types-Standard/deep-coercions.t index b28b30e..080abe7 100644 --- i/t/20-unit/Types-Standard/deep-coercions.t +++ w/t/20-unit/Types-Standard/deep-coercions.t @@ -365,6 +365,28 @@ DICT_PLUS_SLURPY: { ); }; +DICT_PLUS_OPTIONAL: { + my $IntFromStr = declare IntFromStr => as Int; + coerce $IntFromStr, from Str, sub { length($_) }; + $IntFromStr->coercion->freeze; + + my $Dict1 = Dict[ a => $IntFromStr, b => Optional[Int], c => Optional[Int] ]; + ok( + $Dict1->has_coercion && !$Dict1->coercion->can_be_inlined, + "$Dict1 has a non-inlinable coercion", + ); + is_deeply( + $Dict1->coerce({ a => "Hello", b => 1, c => 2 }), + { a => 5, b => 1, c => 2 }, + "Coercion (A) to $Dict1", + ); + is_deeply( + $Dict1->coerce({ a => "Hello", b => 1 }), + { a => 5, b => 1 }, + "Coercion (B) to $Dict1", + ); +}; + TUPLE: { my $IntFromStr = declare IntFromStr => as Int; coerce $IntFromStr, from Str, q{ length($_) };
Thanks for finding and fixing this. I hope to be able to release a fixed version towards the end of this week.
1.000003 released including this fix. Thanks again.