AndyH AndyH - 26 days ago 9
Perl Question

Moose: subtype message does not show up

I am starting to use Moose. Here is my test package code:

package MyTest;
use Moose;
use Moose::Util::TypeConstraints;

subtype 'MyStatus',
as 'Int',
where { $_ >= 0 && $_ < 10 },
message { "Wrong status: $_" };

has status => ( is => 'rw', isa => 'Maybe[MyStatus]' );

no Moose; 1;


And here is the program:

use strict;
use warnings;
use MyTest;

my $t1 = MyTest->new('status' => 3);
$t1->status(100);


I expected to get a "Wrong status: 100" error, but instead I got this:

Attribute (status) does not pass the type constraint because: Validation failed for 'Maybe[MyStatus]' with value 100 at accessor MyTest::s tatus (defined at MyTest.pm line 10) line 4

How to make that message work?
Thank you!

Answer

The Maybe[] eats the error message. If you remove it, it gives the message from your type.

has status => ( is => 'rw', isa => "MyStatus" );

Here's the error:

Attribute (status) does not pass the type constraint because: Wrong status: 100 at accessor MyTest::status (defined at /home/foo/code/scratch.pl line 1331) line 4 MyTest::status('MyTest=HASH(0x3434c58)', 100) called at /home/foo/code/scratch.pl line 1337

It's because the Maybe[] itself is also just a function call. It checks the return value of calling the code ref behind MyStatus with the value you pass to the constructor (here that's 100). If that type check passes , all is well. But if that check fails, Maybe[] issues its own error message.

You should ask yourself this question: Do you really want that the status can be undef? You didn't make it required, so you can omit it. Then your object doesn't have a status, which is different from having an undefined status. A status implies that the object is in a certain state, where the state has a meaning. If that state is undefined it sounds like trouble to me.