houseabsolute / Params-ValidationCompiler

Build an optimized subroutine parameter validator once, use it forever
https://metacpan.org/release/Params-ValidationCompiler/
Other
4 stars 5 forks source link

Pass the varname to Type::Tiny assertions. #23

Open dwright opened 6 years ago

dwright commented 6 years ago

Currently if you are using Types::Standard, or anything else that uses Type::Tiny as its base class to define a type, and one of your parameters fails an assertion, you get a Error::TypeTiny::Assertion object thrown back. But you get no feedback on which of the parameters failed the assertion.

For example, if you have a validator that looks like this:

  $x = validation_for( 
         val1 => { type => Num },
         val2 => { type => Num }
  );

And you happen to pass "Foo" as one of the values, you'll get an exception back that looks like this:

Error::TypeTiny::Assertion  {
    Parents       Error::TypeTiny
    public methods (11) : attribute_name, attribute_step, explain, has_attribute_name, has_attribute_step, has_type, message, new, type, value, varname
    private methods (2) : __ANON__, _build_message
    internals: {
        context       {
            file      "(eval 72)",
            line      51,
            package   "Eval::Closure::Sandbox_1"
        },
        message       "Value "foo" did not pass type constraint "Num"",
        stack_trace   undef,
        type          Type::Tiny,
        value         "foo",
        varname       "$_"
    }
}

But you have no way to programmatically identify if it was val1 or val2 that failed validation.

I hope that it is possible for Params::ValidationCompiler to pass in the name of the parameter as the varname when testing the assertion. Doing so, will (hopefully) cause a more useful value than the default $_ to be returned in the exception.

autarch commented 6 years ago

So from my reading of the Type::Tiny code there's a couple issues.

  1. In the case where the type check is inlined it actually has this information but it intentionally doesn't use it for some reason.
  2. In the case where it's not inlined it doesn't even have an API to do this.

So I'd be happy to fix this in PVC if the TT API allowed me to do so without doing some horrible things.