Background: http://rt.cpan.org/Public/Bug/Display.html?id=48849

This fails:

  coerce ArrayRef[MyObject],
    from ArrayRef[HashRef],
    via  { [ map { MyObject->new($_) } @$_ ] };

  # later
  
  has objects => (isa => ArrayRef[MyObject], coerce => 1);

It succeeds with a subtype of ArrayRef[MyObject] or if the generated type
constraint is saved in a variable and reused in the 'isa'.

This is because parameterizing types with MooseX::Types does not register the
type constraints it generates, so there's nothing linking the two
ArrayRef[MyObject] calls.

I fixed this in MooseX::Types 0.18, and it broke MXMS, because rafl expects
that the parameterized type functions (Dict, Tuple, ArrayRef, etc.) work
differently than I do:

  <@rafl> i think of the parameterized decorators as type generators
  <@rafl> giving me a new instance of a type constraint on every call

This doesn't make any sense to me for most cases, where people are often
hardcoding both the parameterized type name and its argument (e.g.
HashRef[Str]), but I do see the use for being able to generate unregistered
types on demand when building types programmatically.

I'm not sure what to do about this.  I reverted the fix so that MXMS wouldn't
stay broken, but that means that the original MX::Types bug is still there.

Three possibilities come to mind:

1. provide a helper function to twiddle some global in MooseX::Types to avoid
auto-registering the parameterized types that are generated:

  my $tc = unregistered_type_constraint { Tuple[ArrayRef[Str], Int, GlobRef] };

2. Tell people to manually register the parameterized types that they want to
use:

  register_type_constraint ArrayRef[MyObject];

3. Have the 'coerce' sugar automatically register parameterized type
constraints and make sure that there's an alternative API for programmatic TC
generation (e.g. MXMS) to use that avoids the automatic behavior.

hdp.

Reply via email to