How to use Types::Path::Tiny with Moo

coerce, moo, moose, perl, types

Solution

There is no reason to have `use strict;` and `use warnings;` if you have `use Moo;` as it does that for you.

You also have to give Moo a code reference for the `coerce` element, not a true value. The way you get that with Type::Tiny is by calling `$type->coercion`.

package MahewinBlogEngine::Common;

# not needed with Moo
# use strict;
# use warnings;

use Moo;
use Types::Path::Tiny qw/AbsPath/;

...

has 'directory' => (
    is       => 'rw',
    isa      => AbsPath,
    required => 1,
    coerce   => AbsPath->coercion,
);
for( qw'/home ./ ./Documents Documents' ){
  use feature 'say';
  say $_, "\t", MahewinBlogEngine::Common->new( directory => $_ )->directory;
}
/home   /home
./      /home/user
./Documents     /home/user/Documents
Documents       /home/user/Documents

Problem

My first question on this site, I come quickly. I'm a developer, I mainly use Python and Perl. I am passionate and I really like the development. My first question is about Perl, Moo, and Type::Tiny. Type::Tiny is a great module for use with Moo of course, but I will return to this subject in another question. I discovered Types::Path::Tiny a module coercions for Moose and Moo, so I tried to make a attribute directory in my class like as described in the documentation, as my project was in Moose it work, but since I moved in Moo, it no longer works: ``` package MahewinBlogEngine::Common; use strict; use warnings; use feature "state"; use Moo; use Types::Path::Tiny qw/Path AbsPath/; use CHI; use MahewinBlogEngine::Renderer; use Type::Params qw( compile ); use Types::Standard qw( slurpy Object Str HashRef ArrayRef ); =attr directory rw, required, Str. The directory contain articles. =cut has 'directory' => ( is => 'rw', isa => AbsPath, required => 1, coerce => 1, ); ``` In my tests directory: ``` my $articles = MahewinBlogEngine->articles( directory => getcwd() . '/t/articles' ); ``` Error is: ``` Invalid coerce '1' for MahewinBlogEngine::Common->directory not a coderef or code-convertible object at /home/hobbestigrou/perl5/perlbrew/perls/perl-5.19.1/lib/site_perl/5.19.1/Method/Generate/Accessor.pm line 618. Compilation failed in require at /home/hobbestigrou/perl5/perlbrew/perls/perl-5.19.1/lib/site_perl/5.19.1/Module/Runtime.pm line 317. Compilation failed in require at /home/hobbestigrou/MahewinBlogEngine/lib/MahewinBlogEngine.pm line 8. BEGIN failed--compilation aborted at /home/hobbestigrou/MahewinBlogEngine/lib/MahewinBlogEngine.pm line 8. Compilation failed in require at ./benchmark.pl line 10. BEGIN failed--compilation aborted at ./benchmark.pl line 10. ``` This is normal, because with Moo the coercion is a coderef so I tried: ``` has 'directory' => ( is => 'rw', isa => AbsPath, required => 1, coerce => sub { return "Path" } ); ``` Error is: ``` value "Path" did not pass type constraint "Path" (not isa Path::Tiny) (in $self->{"directory"}) at (eval 355) line 99. ``` If I have no coerce: ``` value "/home/hobbestigrou/MahewinBlogEngine/t/articles" did not pass type constraint "Path" (not isa Path::Tiny) (in $self->{"directory"}) at (eval 355) line 89. ``` I'm sorry for this simple question, I must be stupid and miss something, but I do not see what maybe I was missing something in the doc. Thanks

Original source