Skip to content

Type::Params: unexpected error when die'ing in goto_next in a multiple signature #154

@djerius

Description

@djerius

Type::Tiny 2.004000

I'm trying to handle a legacy API issue by using multiple signatures. The old API is

foo( $hashref, %options )

i.e., first is positional, rest are named.

The new API is

foo( head => $hashref, %options );

i.e., all are named.

In order to transparently convert from the first to the second, I'm doing this:

sub goto_next {
    $_[1]{head} = $_[0];
    return $_[1];
}

signature_for foo => (
    multiple => [ {
            # legacy
            goto_next => \&goto_next,
            head      => [Str],
            named     => [ uri => Optional [Any], head => Optional [Any] ],
        },
        {
            # new
            named => [ head => Str, uri => Optional [Any] ]
        },
    ],
);
sub foo { p @_ }

I need to provide the head parameter to the named options for the legacy API otherwise the constructed parameter class doesn't have a head attribute.

This however leaves open the possibility that this call:

foo( $head_value, head => $another_head_value );

could arise if someone tweaked %options to include head and forgot to fix the actual call.

So I figured I could catch this via:

sub goto_next {
    die "legacy API: do not supply a named 'head' parameter"
      if $_[1]->has_head;
    $_[1]{head} = $_[0];
    return $_[1];
}

But this call

foo( 'foo', head => undef );

results in a rather unexpected error:

$ perl boom.pl
Use of uninitialized value in pattern match (m//) at ../5.36/lib/perl5/site_perl/5.36.1/Error/TypeTiny.pm line 61.
Use of uninitialized value in pattern match (m//) at ../5.36/lib/perl5/site_perl/5.36.1/Error/TypeTiny.pm line 61.
Parameter validation failed at file? line NaN.

While debugging, I reverted to a similar approach with a single signature, i.e.

signature_for foo => (
    goto_next => \&goto_next
    head  => [Str],
    named => [ uri => Optional [Any], head => Optional [Any] ],
);

With the result that the call

foo( 'foo', head => undef );

results in the expected outcome:

$ perl tst.pl
legacy API: do not supply a named 'head' parameter at tst.pl line 9.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions