Skip Menu |

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

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

People
Owner: perl [...] toby.ink
Requestors: marc.ballarin [...] 1und1.de
Cc:
AdminCc:

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



Subject: Nasty interaction between compile() and $1
Date: Thu, 19 Apr 2018 15:49:11 +0200
To: bug-Type-Tiny [...] rt.cpan.org
From: Marc Ballarin <marc.ballarin [...] 1und1.de>
Hi, I came across the following, surprising interaction between compile() with certain types and capture variables. I am slightly surprised, I did not notice this earlier, since I use Type::Tiny a lot, and for quite some time. It seems, that a compiled Int-check destroys the passed in value, after successfully validating it, if a capture variable was passed in directly. It works fine, if a temporary variable is used. The output of the script below is like this: *** using direct $1 Use of uninitialized value $int in concatenation (.) or string at type.pl line 11. after TT Int check: '' after manual Int check: '123' after TT Str check: '123' after assert_valid Int check: '123' *** using temporary after TT Int check: '123' after manual Int check: '123' after TT Str check: '123' after assert_valid Int check: '123' Regards, Marc Test script: #!/usr/bin/perl use 5.014; use warnings; use Type::Params qw(compile); use Types::Standard qw(Str Int); sub check_int_tt_compile {     state $check = compile(Int);     my ($int) = $check->(@_);     say "after TT Int check: '$int'"; } sub check_str_tt {     state $check = compile(Str);     my ($int) = $check->(@_);     say "after TT Str check: '$int'"; } sub check_int_manual {     my ($int) = @_;     die "no Int!" unless $int =~ /^\d+$/xa;     say "after manual Int check: '$int'"; } sub check_int_tt_no_compile {     my ($int) = @_;     Int->assert_valid($int);     say "after assert_valid Int check: '$int'"; } my $string = 'a123'; say '*** using direct $1'; if ($string =~ /a(\d+)/xa) {     check_int_tt_compile($1);     check_int_manual($1);     check_str_tt($1);     check_int_tt_no_compile($1); } say '*** using temporary'; if ($string =~ /a(\d+)/xa) {     my $matched = $1;     check_int_tt_compile($matched);     check_int_manual($matched);     check_str_tt($matched);     check_int_tt_no_compile($matched); }
Interesting. Integer validation does use a regexp, so this might be unavoidable. But I'll see what can be done.
Patched in the repo: https://github.com/tobyink/p5-type-tiny/compare/9108dc4...5964e8e This is gonna slow down Int checks somewhat, but sadly I think it needs to be done for correctness.
This seems to be a similar issue in Params::Util https://rt.cpan.org/Ticket/Display.html?id=87649
Fixed in 1.004000.