Subject: | Missing coercion with Moose and Type::Tiny |
If you have a Moose class that inherits from a Moo class that has an attribute with a Type::Tiny
type constraint which defines a coercion, then the coercion disappears and you get the following
error
You cannot coerce an attribute (path) unless its type (Directory) has a coercion at /usr/local/share/perl/5.10.1/Moo/HandleMoose.pm line 146.
Test and patch attached
Regards
Subject: | MyTypes.pm |
package MyTypes;
use strict;
use warnings;
use namespace::clean -except => 'meta';
use Type::Library -base, -declare => qw( Path Directory );
use Type::Utils;
BEGIN { extends q(Types::Standard) };
{ package IO::Class;
sub new { shift; bless { path => $_[ 0 ] }, 'IO::Class' }
sub is_dir { -d $_[ 0 ]->path }
sub path { $_[ 0 ]->{path} }
}
declare Path, as Object,
where { $_->isa( q(IO::Class) ) }, message { 'Wrong class' };
declare Directory, as Path, where { $_->is_dir }, message { 'Not a directory' };
coerce Directory, from Str, via { IO::Class->new( $_ ) };
coerce Path, from Str, via { IO::Class->new( $_ ) };
1;
__END__
Subject: | moo-handlemoose.patch |
--- HandleMoose.pm 2013-06-15 21:33:19.000000000 +0100
+++ HandleMoose.pm 2013-06-15 21:34:29.000000000 +0100
@@ -114,7 +114,7 @@
my $type = $mapped->();
Scalar::Util::blessed($type) && $type->isa("Moose::Meta::TypeConstraint")
or die "error inflating attribute '$name' for package '$_[0]': \$TYPE_MAP{$isa} did not return a valid type constraint'";
- $coerce ? $type->create_child_type(name => $type->name) : $type;
+ $coerce ? $type->create_child_type(name => $type->name, coercion => 1) : $type;
} else {
Moose::Meta::TypeConstraint->new(
constraint => sub { eval { &$isa; 1 } }
Subject: | moose-type_tiny-coercion.t |
use strictures 1;
use Test::More;
use Test::Exception;
use lib 'xt/lib';
{ package TC1;
use Moo;
use MyTypes qw( Directory );
has 'path' => is => 'ro', isa => Directory, coerce => Directory->coercion;
}
{ package TC2;
use Moose;
extends 'TC1';
}
my $tc; eval { $tc = TC2->new( path => 't' ) };
ok defined $tc, 'Failed to construct coercion test case';
defined $tc
and is $tc->path->path, 't', 'Moose + Inheritance + Type::Tiny + Coercion';
done_testing;