-
-
Notifications
You must be signed in to change notification settings - Fork 48
Description
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.