I've created subtype Birth_d
with coercion as shown below, and I'm trying to use it in combination with the built-in Maybe
type, per Moose::Manual::Types.
I'm getting the error You cannot coerce an attribute (birth_d) unless its type (Maybe[Birth_d]) has a coercion
. Here's complete test code:
package Student;
use Moose;
use Moose::Util::TypeConstraints;
use DateTime::Format::MySQL;
class_type 'Birth_d', { class => 'DateTime' };
coerce 'Birth_d',
from 'Str',
via { DateTime::Format::MySQL->parse_date( $_ ) };
has 'name' => (
isa => 'Str',
is => 'ro',
);
has 'birth_d' => (
isa => 'Maybe[Birth_d]', # This works: isa => 'Birth_d'
coerce => 1,
is => 'ro',
);
package main;
use Test::More;
my $student = Student->new(
name => 'Johnnie Appleseed',
birth_d => '2015-01-01'
);
is ( $student->birth_d->ymd(), '2015-01-01' );
my $student2 = Student->new(
name => 'Foo Bar',
birth_d => undef
);
is( $student2->birth_d, undef );
Replacing isa => 'Maybe[Birth_d]'
with isa => 'Birth_d'
works, but is not what is needed. I need to make the birth_d optional, and if not supplied, should be undef.
I should add, I tried using MooseX::Types to tuck this Birth_d type away in a separate place, but found its cavalier use of barewords a bit unorthodox, so I slowly backed away. I'm open to reconsidering it, if it makes sense to do so.
I would find it more useful to not have a Maybe[Birth_d] type, but simply declare the attribute with the Birth_d type, and no "required" set.
That way, if a valid String is passed in, it will be accepted, an invalid String will lead to an error, and nothing just does not need to be passed in.
However, you can coerce to a maybe type:
subtype 'MaybeBirth_d',
as maybe_type(class_type('DateTime'));
coerce 'MaybeBirth_d',
from 'Str',
via { DateTime::Format::MySQL->parse_date( $_ ) };
has 'birth_d' => (
isa => 'MaybeBirth_d',
coerce => 1,
is => 'ro',
);
I just do not see the value of being able to pass in undef for a birthdate - how is that better than not setting it?
I would also like to suggest using no Moose::Util::TypeConstraints;
and no Moose;
at the end of your package, or namespace::autoclean;
at the beginning, as well as __PACKAGE__->meta->make_immutable;
at the end of your Student class.