驼鹿类型很棒,但有时你需要更具体.大家都知道,这些数据类型的规则:该参数可能只'A','B'或者'C',或者只有一个货币符号,或者必须符合一些正则表达式.
请看下面的示例,该示例具有两个约束属性,一个必须是'm'或者'f',另一个必须是有效的ISO日期.Moose指定这些约束的最佳方法是什么?我想到了SQL CHECK子句,但是AFAICS check在Moose中没有关键字.所以我用过trigger,但听起来不对.有谁有更好的答案?
package Person;
use Moose;
has gender => is => 'rw', isa => 'Str', trigger =>
sub { confess 'either m or f' if $_[1] !~ m/^m|f$/ };
has name => is => 'rw', isa => 'Str';
has dateOfBirth => is => 'rw', isa => 'Str', trigger =>
sub { confess 'not an ISO date' if $_[1] !~ m/^\d\d\d\d-\d\d-\d\d$/ };
no Moose;
__PACKAGE__->meta->make_immutable;
package main;
use Test::More;
use Test::Exception;
dies_ok { Person->new( gender => 42 ) } 'gender must be m or f';
dies_ok { Person->new( dateOfBirth => 42 ) } 'must be an ISO date';
done_testing;
Run Code Online (Sandbox Code Playgroud)
以下是我最后使用的内容:
package Blabla::Customer;
use Moose::Util::TypeConstraints;
use Moose;
subtype ISODate => as 'Str' => where { /^\d\d\d\d-\d\d-\d\d$/ };
has id => is => 'rw', isa => 'Str';
has gender => is => 'rw', isa => enum ['m', 'f'];
has firstname => is => 'rw', isa => 'Str';
has dateOfBirth => is => 'rw', isa => 'ISODate';
no Moose;
__PACKAGE__->meta->make_immutable;
Run Code Online (Sandbox Code Playgroud)
这是Moose版本1.19,如果它很重要.我错误地引入了错误的 subtype as => 'Str', where => { ... }语法,我收到了以下警告:Calling subtype() with a simple list of parameters is deprecated.所以我不得不根据精细的手册改变它.
只需定义自己的子类型,然后使用它.
package Person;
use Moose::Util::TypeConstraints;
use namespace::clean;
use Moose;
has gender => (
is => 'rw',
isa => subtype(
as 'Str',
where { /^[mf]$/ }
),
);
has name => (
is => 'rw',
isa => 'Str'
);
has dateOfBirth => (
is => 'rw',
isa => subtype(
as 'Str',
where { /^\d\d\d\d-\d\d-\d\d$/ }
),
);
no Moose;
__PACKAGE__->meta->make_immutable;
1;
Run Code Online (Sandbox Code Playgroud)
package main;
use Test::More;
use Test::Exception;
dies_ok { Person->new( gender => 42 ) } 'gender must be m or f';
dies_ok { Person->new( dateOfBirth => 42 ) } 'must be an ISO date';
done_testing;
Run Code Online (Sandbox Code Playgroud)
或者您可以使用MooseX :: Types模块.
package Person::TypeConstraints;
use MooseX::Types::Moose qw'Str';
use MooseX::Types -declare => [qw'
Gender ISODate
'];
subtype Gender, (
as Str,
where { /^[mf]$/ },
);
subtype ISODate, (
as Str,
where { /^\d\d\d\d-\d\d-\d\d$/ }
);
1;
Run Code Online (Sandbox Code Playgroud)
package Person:
use MooseX::Types::Moose qw'Str';
use Person::TypeConstraints qw'Gender ISODate';
use namespace::clean;
use Moose;
has gender => (
is => 'rw',
isa => Gender,
);
has name => (
is => 'rw',
isa => Str,
);
has dateOfBirth => (
is => 'rw',
isa => ISODate,
);
no Moose;
__PACKAGE__->meta->make_immutable;
1;
Run Code Online (Sandbox Code Playgroud)