Question

Have:

package MyPath;
use strict;
use warnings;
use Moose;

has 'path' => (
    is => 'ro',
    isa => 'Path::Class::Dir',
    required => 1,
);
1;

But want create this object with two ways, like:

use strict;
use warnings;
use MyPath;
use Path::Class;
my $o1 = MyPath->new(path => dir('/string/path')); #as Path::Class::Dir
my $o2 = MyPath->new(path => '/string/path'); #as string (dies - on attr type)

And when call it with a 'Str' - want convert it internally in the MyPath package to Class::Path::Dir, so, both: $o1->path and $o2->path should return blessed Path::Class::Dir

When I tried extend the definition to the next:

has 'path' => (
    is => 'ro',
    isa => 'Path::Class::Dir|Str',    #allowing both attr types
    required => 1,
);

It doesn't works and still need "somewhat" convert the Str to Path::Class::Dir automatically-internally in the package MyPath...

Could someone give me some hints?

EDIT: Based on Oesor's hint I found than i need someting like:

coerce Directory,
    from Str,       via { Path::Class::Dir->new($_) };

has 'path' => (
    is => 'ro',
    isa => 'Directory',
    required => 1,
);

But still havent idea how to correctly use it...

Some more hints please?

Was it helpful?

Solution

You're looking for type coersion.

use Moose;
use Moose::Util::TypeConstraints;
use Path::Class::Dir;

subtype 'Path::Class::Dir',
   as 'Object',
   where { $_->isa('Path::Class::Dir') };

coerce 'Path::Class::Dir',
    from 'Str',
        via { Path::Class::Dir->new($_) };

has 'path' => (
    is       => 'ro',
    isa      => 'Path::Class::Dir',
    required => 1,
    coerce   => 1,
);

OTHER TIPS

Hint -- look for how to coerce the value:

https://metacpan.org/pod/Moose::Manual::Types

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top