Skip Menu |

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

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

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

Bug Information
Severity: Unimportant
Broken in: 0.012
Fixed in: (no value)



Subject: deep recursion error for many valued Enum + Undef
The following code on Perl 5.22.1, Type::Tiny 1.002, Type::Tiny::XS 0.012 { package MyTypes; use strict; use warnings; use Type::Library -base, -declare => qw( Filetype ); use Type::Utils -all; use Types::Standard qw[ Enum ]; declare Filetype, as Enum [ 0 .. 200 ]; } { package Bar; use Types::Standard qw[ Undef ]; use Moo; # causes deep recursion has foo => ( is => 'rw', isa => MyTypes::Filetype | Undef ); # does not cause deep recursion has bar => ( is => 'rw', isa => MyTypes::Filetype ); } results in Deep recursion on subroutine "Type::Tiny::XS::_handle_expr" at [...]/Type/Tiny/XS.pm line 147. Deep recursion on subroutine "Type::Tiny::XS::_handle_expr" at [...]/Type/Tiny/XS.pm line 147. This happens only if Filetype | Undef is used. If just Filetype is used, the error does not occur. Thanks, Diab
This is probably a Type-Tiny-XS problem rather than Type-Tiny itself.
Hmm, problem is that the list of values 0..200 in some places gets processed a bit like this (pseudocode): sub process { my ($head, @tail) = @_; do_something($head); process(@tail); } Leading to a function getting called recursively 201 times. This is in Type::Tiny::XS's code for transforming a string like "Enum['a','b']" into a coderef. It may be possible to rewrite this to not use recursion. In the mean time, I'll suggest: use Types::Common::Numeric qw(PositiveInt); declare Filetype, as PositiveInt->where(q{ $_ <= 200 });
On Fri Jun 02 03:15:45 2017, TOBYINK wrote: Show quoted text
> This is probably a Type-Tiny-XS problem rather than Type-Tiny itself.
Sorry about that. I noticed the XS in the error message just after I submitted the ticket.
On Fri Jun 02 03:27:14 2017, TOBYINK wrote: Show quoted text
> Hmm, problem is that the list of values 0..200 in some places gets > processed a bit like this (pseudocode): > > sub process { > my ($head, @tail) = @_; > do_something($head); > process(@tail); > } > > Leading to a function getting called recursively 201 times. This is in > Type::Tiny::XS's code for transforming a string like "Enum['a','b']" > into a coderef. > > It may be possible to rewrite this to not use recursion. > > In the mean time, I'll suggest: > > use Types::Common::Numeric qw(PositiveInt); > declare Filetype, as PositiveInt->where(q{ $_ <= 200 });
It's actually about 200+ strings. It turns out that splitting it into a bunch of smaller Enum Types and creating a Union of them avoids the error when combined with Undef. Thanks.
Type::Tiny::Enum will now avoid trying to generate an XS coderef for enums of more than 50 strings.
On Tue Aug 18 16:22:03 2020, TOBYINK wrote: Show quoted text
> Type::Tiny::Enum will now avoid trying to generate an XS coderef for > enums of more than 50 strings.
Thanks!
Resolved by latest Type::Tiny release