3

有:

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

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

但是想用两种方式创建这个对象,比如:

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)

当使用 'Str' 调用它时 - 想要在 MyPath 包中将其内部转换为 Class::Path::Dir,因此,both:$o1->path$o2->path应该返回祝福Path::Class::Dir

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

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

它不起作用,仍然需要“在某种程度上”在内部自动转换Str为...Path::Class::Dirpackage MyPath

有人可以给我一些提示吗?

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

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

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

但是仍然不知道如何正确使用它...

请问还有更多提示吗?

4

2 回答 2

5

您正在寻找类型强制。

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,
);
于 2013-10-27T23:00:54.280 回答
0

提示——寻找如何强制值:

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

于 2013-10-27T21:06:27.280 回答