p5-type-tiny icon indicating copy to clipboard operation
p5-type-tiny copied to clipboard

RFE: Type::Params: coerce undef to default value

Open djerius opened this issue 2 years ago • 2 comments

It would be useful to be able to define a parameter signature which would coerce undef to the default value for the parameter. As an example, with a signature of

signature_for table_generator => (
    named => [
        cell_span => Enum[ DISPLAY_CELL_SPANS ],
                     { default => DISPLAY_CELL_SPAN_MULTI },
);

I currently have to check that the cell_span parameter is defined before passing it, otherwise I'll get a type error, which leads to things like this:

my $generator = table_generator(
    ( defined $args{cell_cpan} ?
      ( cell_cpan => delete $args{cell_cpan} ) : () ),
);

If the bike-sheddable undef_is_default flag was set for the cell_span parameter, then this would turn into:

my $generator = table_generator(
      cell_cpan => delete $args{cell_cpan}
);

PerlX::Maybe is an option, but I believe that the ability to conditionally coerce undef to the default in the signature results in clearer code.

djerius avatar May 20 '23 20:05 djerius

I'd suggest doing something like:

signature_for table_generator => (
    named => [
        cell_span => Maybe [ Enum[ DISPLAY_CELL_SPANS ] ]
    ...
);

my $cell_span = $args->cell_span // DISPLAY_CELL_SPAN_MULTI;

tobyink avatar May 22 '23 16:05 tobyink

That does move the logic out of the caller, but it moves the setting of defaults for this parameter out of the signature and into the body of the subroutine.

If multiple parameters have defaults, specifying them in a single place makes for more understandable and maintainable code; I find that the signature is the natural place for them, as the boilerplate code required to initialize them outside of the signature detracts from the purpose of the subroutine. Having them in the signature provides both aesthetic and functional benefits.

There will always be oddball parameters requiring some sort of custom initialization which won't fit into the signature, but I think that passing undef is sufficiently common that it warrants specialized support in the signature.

djerius avatar May 22 '23 17:05 djerius