Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inherit coercions with "->where()"? #164

Open
pipatron opened this issue Jan 22, 2025 · 0 comments
Open

Inherit coercions with "->where()"? #164

pipatron opened this issue Jan 22, 2025 · 0 comments

Comments

@pipatron
Copy link

I'm sure this must have come up before but I couldn't really find any discussion when searching!

I think Type::Tiny could be easier to use if ...->where(...) automatically inherits all its parent's coercions. It makes sense in what I believe are the typical cases, and if it doesn't make sense, there's the very simple ...->no_coercions or just don't enable coercions when using the type.

Nested coercions for ArrayRef[] is very cool and almost magic, but I find that it gets difficult and annoying as soon as I want to deviate a bit. Take the example where I want to modify the type just a little with ...->where(...):

package Box {
  use Moo;
  use Types::Standard qw( ArrayRef Bool );

  # an ODD assortment of bits
  has bits => (
    is     => 'ro',
    isa    => ArrayRef->of(Bool)->where('@$_ % 2'),
    coerce => 1,
  );
}

my $gift = Box->new(bits=>[0,1,2]); # 2 should coerce to 1 but fails
Reference [0,1,2] did not pass type constraint (in $args->{"bits"}) at where.pl line 12
    "__ANON__" is a subtype of "ArrayRef[Bool]"
    Reference [0,1,2] did not pass type constraint "ArrayRef[Bool]" (in $args->{"bits"})
    "ArrayRef[Bool]" constrains each value in the array with "Bool"
    Value "2" did not pass type constraint "Bool" (in $args->{"bits"}->[2])
    "Bool" is defined as: (!ref $_ and (!defined $_ or $_ eq q() or $_ eq '0' or $_ eq '1'))

I don't see why coercions would not be inherited here, and it seems difficult or at least unwieldy to restore them. Something like this works:

    isa    => ArrayRef->of(Bool)->where('@$_ % 2')->plus_coercions(
      ArrayRef->of(Bool)->coercibles, sub { ArrayRef->of(Bool)->coerce($_) }
    ),

Or is there perhaps a simpler way to do this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant