Perl 定义和转换驼鹿属性类型的正确方法

Perl 定义和转换驼鹿属性类型的正确方法,perl,moose,Perl,Moose,拥有: 但您希望通过两种方式创建此对象,如: package MyPath; use strict; use warnings; use Moose; has 'path' => ( is => 'ro', isa => 'Path::Class::Dir', required => 1, ); 1; 当使用“Str”调用它时,希望在MyPath包中内部将其转换为Class::Path::Dir,因此:$o1->Path和$o2->Path都应

拥有:

但您希望通过两种方式创建此对象,如:

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

has 'path' => (
    is => 'ro',
    isa => 'Path::Class::Dir',
    required => 1,
);
1;
当使用“Str”调用它时,希望在MyPath包中内部将其转换为Class::Path::Dir,因此:
$o1->Path
$o2->Path
都应该返回
Path::Class::Dir

当我尝试将定义扩展到下一个:

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)
它不起作用,仍然需要在
包MyPath
内部自动地将
Str
转换为
Path::Class::Dir

有人能给我一些提示吗

编辑:根据Oesor的提示,我发现我需要一些东西,比如:

has 'path' => (
    is => 'ro',
    isa => 'Path::Class::Dir|Str',    #allowing both attr types
    required => 1,
);
但仍然不知道如何正确使用它

请提供更多提示?

提示--查看如何强制该值:


您正在寻找类型协同

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

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

你能再加一些提示吗?我编辑了我的问题。。。(可能还需要1-2行-你能给我一个答案吗?:)你的
subtype'Path::Class::Dir'…
声明可以更自然地写成
Class\u type'Path::Class::Dir'
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,
);