Skip Menu |

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

Report information
The Basics
Id: 127504
Status: rejected
Priority: 0/
Queue: Type-Tiny

People
Owner: perl [...] toby.ink
Requestors: kfm [...] plushkava.net
Cc:
AdminCc:

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



Subject: Ambiguous exceptions where used with Params::ValidationCompiler
Hello. I like Params::ValidationCompiler very much for its Perlish API and its performance. Up until now, I had been using it with Specio. However, after being bowled over by the performance of Type::Tiny::XS, I experimented with the conversion of one of my projects, only to find that debugging becomes extremely difficult. Consider the attached program, which prints the following:- *** Params::ValidationCompiler/Specio *** Validation failed for type named ArrayRef[Int] declared in package main (type-tiny-issue.pl) at line 11 in sub named main::a with value [ "str" ] *** Params::ValidationCompiler/Type::Tiny *** Reference ["str"] did not pass type constraint "ArrayRef[Int]" at (eval 153) line 26 *** Function::Parameters/Type::Tiny *** In fun c: parameter 2 ($aref): Reference ["str"] did not pass type constraint "ArrayRef[Int]" at type-tiny-issue.pl line 32. The exception produced by the combination of Params::ValidationCompiler and Type::Tiny makes it impossible to know exactly where in the program it was thrown. What's interesting is that Specio manages it, somehow. Would there be any feasible way for Type::Tiny to behave similarly?
Subject: type-tiny-demo.txt
#!/usr/bin/perl use 5.10.1; use Function::Parameters 2; use Params::ValidationCompiler qw(validation_for); use Specio::Library::Builtins; use Try::Tiny; use Types::Standard qw(Str Int ArrayRef HashRef Map Maybe); sub a { state $validator = validation_for(params => [ { type => t('Str') }, { type => t('ArrayRef' => of => t('Int')) }, { type => t('HashRef') } ]); my ($str, $aref, $map) = $validator->(@_); } sub b { state $validator = validation_for(params => [ { type => Str }, { type => ArrayRef[Int] }, { type => HashRef } ]); my ($str, $aref, $map) = $validator->(@_); } fun c (Str $str, ArrayRef[Int] $aref, HashRef $map) {} try { a(1, ['str'], {}); } catch { say for '*** Params::ValidationCompiler/Specio ***', (split /\n/)[0]; }; try { b(1, ['str'], {}); } catch { say for '*** Params::ValidationCompiler/Type::Tiny ***', (split /\n/)[0]; }; try { c(1, ['str'], {}); } catch { say for '*** Function::Parameters/Type::Tiny ***', (split /\n/)[0]; };
Firstly, you should be aware that the exception thrown by Type::Tiny is a blessed object which overloads stringification. You can catch it and call a method on it to get a full stack trace. (See Error::TypeTiny.) Secondly, Params::ValidationCompiler is mostly written with Specio in mind, and I don't know exactly how much effort Dave Rolsky puts into supporting Type::Tiny. It works for sure, and is officially supported, but I don't know if it's *as* supported as Specio type constraints are. However, Params::ValidationCompiler is basically a Specio version of a parameter checking module which is already bundled with Type::Tiny called Type::Params. If you use Type::Params, you'll definitely get more useful error messages. use Type::Params qw(compile); sub b { state $validator = compile(Str, ArrayRef[Int], HashRef); my ($str, $aref, $map) = $validator->(@_); } Gives you this: *** Params::ValidationCompiler/Type::Tiny *** Reference ["str"] did not pass type constraint "ArrayRef[Int]" (in $_[1]) at blah.pl line 28
PS: you'll notice that Type::Params has a more concise syntax in most cases too, and is usually marginally faster --- though there's not much speed difference; Dave Rolsky copied a lot of ideas from me, and I copied a few ideas back; they generate pretty similar coderefs.
On Wed Nov 07 12:36:22 2018, TOBYINK wrote: Show quoted text
> PS: you'll notice that Type::Params has a more concise syntax in most > cases too, and is usually marginally faster --- though there's not > much speed difference; Dave Rolsky copied a lot of ideas from me, and > I copied a few ideas back; they generate pretty similar coderefs.
I appreciate your taking the time to explain all of this. Not only are the exception messages sufficiently useful, but I am finding Type::Params - as aided by Type::Tiny::XS - to be the performance leader, with Params::ValidationCompiler + Type::Tiny::XS coming in a fairly close second. Duly compelled by my immediate needs, I converted my project to use Type::Params. While it would still be nice for this issue to be addressed, I am a happy camper. Thanks for a great module.
Closing this as I think it's a Params::ValidationCompiler issue.