Question

This is sure very simple question, but i'm still learning and not found the answer.

Need check the validity of the supplied (required) argument to Moose object constructor, e.g. like in the next example:

use 5.016;
use warnings;

package My {
    use Moose;
    has 'mydir' => (
        is          => 'ro',
        isa         => 'Str',
        required    => 1,
    );
}

use File::Path qw(remove_tree);
package main {
    my @dirs = qw(./d1 ./d2);

    #ensure no one dir exists
    remove_tree($_) for ( @dirs );

    #create the first dir
    mkdir $dirs[0] or die;

    foreach my $dir( @dirs ) {
        my $m = My->new( mydir=>$dir );
        say "$dir ", defined($m) ? "" : "NOT", " ok";
    }
}

The question is: what i should add to the My package to ensure create the My object only if the supplied mydir path exists? So somewhere need add the test if -d ... .

How to define the attribute mydir with validity check?

Wanted result of the main program:

./d1 ok
./d2 NOT ok
Was it helpful?

Solution

You can define a subtype with a type constraint.

The syntactic sugar for working with this is provided by Moose::Util::TypeConstraints.

package My;
use 5.16.0;

use Moose;
use Moose::Util::TypeConstraints; # provides sugar below

subtype 'ExistingDir' => (
    as 'Str',
    where { -d $_ },
    message { 'The directory does not exist' }
    );

has 'mydir' => (
        is          => 'ro',
        isa         => 'ExistingDir',
        required    => 1,
    );

package main;

my $foo = My->new(mydir => 'perl'); # exists
say $foo->mydir();

my $bar = My->new(mydir => 'perlXXX'); # does not exist, so dies here...

outputs:

>mkdir perl
>perl foo.pl

perl
Attribute (mydir) does not pass the type constraint because: The directory does not exist at ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top