2011-04-28 2 views
5

Moose types이 우수하지만 때로는 좀 더 구체적이어야합니다. 이 데이터 형식 규칙은 모두 'A', 'B' 또는 'C'이거나 통화 기호 만 있거나 일부 정규 표현식을 준수해야합니다.무스 (Moose) 유형에 특정 검사를 적용하면

두 개의 제한된 특성을 갖는 다음 예제를 참조하십시오. 하나는 'm' 또는 'f'이어야하며 다른 하나는 유효한 ISO 날짜 여야합니다. 이러한 제약 조건을 지정하기위한 무스의 가장 좋은 방법은 무엇입니까? 나는 SQL CHECK 절을 생각 하겠지만 AFAICS에는 무스에 check 키워드가 없습니다. 그래서 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; 

는 여기에 내가 사용하여 상처 내용은 다음과 같습니다

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; 

이이 중요한 경우에, 무스 버전 1.19입니다. 에 대해 다음과 같은 경고가 나타납니다.subtype as => 'Str', where => { ... } 구문을 잘못 입력했습니다. Calling subtype() with a simple list of parameters is deprecated. 그래서 나는 훌륭한 매뉴얼에 따라 조금 바꿔야 만했다.

+1

** 답변 : ** 자신 만의 유형을 사용하십시오. –

답변

6

자신의 하위 유형을 정의한 다음 사용하십시오.

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; 

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; 
아니면 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; 
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; 
+2

무스에 Enum TypeConstraint가있을 때 'Str'유형에 의존한다고 말해야합니다. 'gender => (isa => enum ([qw | M m F f |]))가 잘못되어 무엇이 잘못 되었습니까? => 'ro'); – perigrin

+0

나는'Moose :: Util :: TypeConstraints'를 사용하여 감았는데, 이것은 대상 시스템에 이미 설치되어 있다는 장점이 있습니다. 나는 다른 제안들도 흥미 있다고 확신한다. 'subtype'을 호출하는 구문이 예제에서 제시된 것과 약간 다르므로 업데이트를 게시 할 곳의 초기 게시물을 확인하십시오. 내가 찾은'enum '도 편리합니다. 엄청 고마워! – Lumi

+0

나는 시정을해야합니다. Brad의'subtype'에 대한 구문은 훌륭했습니다. 나는'subtype as => 'Str'을 작성하여 빈을 쏟았는데, 여기서 => {...}'는 잘못되었거나 더 이상 사용되지 않습니다. 이 속성은 다른 속성 수정 자와 다르게 철자를 쓰는 것이 약간 까다 롭습니다. – Lumi

3

말했다

use Moose::Util::TypeConstraints; 

my $gender_constraint = subtype as 'Str', where { $_ =~ /^[FfMm]$/ }; 
has gender => (is => 'rw', isa => $gender_constraint); 
+0

그건 그걸 할 수있는 방법 중 하나지만, 한 번만 사용하고 여러 파일을 하나의 파일로만 사용하는 것이 좋습니다.두 개 이상의 파일에 대해 동일한 제약 조건을 사용하려는 경우 [MooseX :: Types] (http://search.cpan.org/perldoc/MooseX::Types)를 사용하는 것이 좋습니다. –

+0

감사. 브래드는 100 % 동의하지 않는 것 같지만, 하나의 범위에만 국한 될지라도 하위 유형의 반환 값을 저장하고 재사용하는 것이 좋습니다. 어쩌면 그게 네가 원하는거야? – Lumi

+0

@ Michael-Ludwig 예, 저는 종종 $ abs_int와 같은 것을 하나의 클래스에서 여러 곳에서 사용하기 때문에 잘 작동합니다. Brad는 MooseX :: Types가 여러 파일에서 동일한 제약 조건을 사용하고 있고 하위 유형을 인라인하면 단일 제약 조건에 적합하다는 점에서 굉장합니다. – SymKat

0

당신은 당신이 현재 (테스트되지 않은, 단지 스케치) 사건에 대한 매개 변수를 형식을 구현하는 MooseX-Types-Parameterizable를 사용하여 시도해 볼 수도 있습니다 :

다음과 같이 사용하십시오.

use YourTypes qw(OneOfStr MatchingStr); 

has gender => (is => 'ro', isa => OneOfStr[ [qw(f m)] ]); 
has dob => (is => 'ro', isa => MatchingStr[ qr/^$yourregex$/ ]); 
+0

고마워, 내가 살펴볼 게. 내일 :-) – Lumi

관련 문제