我尝试创建类型_Varchar
但未成功使用其他类型_VarcharRange
作为参数。反过来,_VarcharRange
可以从其中一种Moose基类型中强制执行。
让我以_Varchar_Range
为例开始
package MyTypes;
use strict;
use warnings;
use Moose;
use MooseX::Types::Moose qw(Str Int ArrayRef HashRef);
use MooseX::Types::Common::Numeric qw( PositiveOrZeroInt );
use MooseX::Types::Parameterizable qw(Parameterizable);
use MooseX::Types -declare=>[qw(_VarcharRange)];
subtype _VarcharRange,
as HashRef[PositiveOrZeroInt], # Must ask for it from MooseX
where {
return 0 if ( grep {$_ ne 'min' && $_ ne 'max' } keys %{$_});
return ( $_->{min} <= $_->{max} ) if ( defined $_->{max} && defined $_->{min} );
return 1;
},
message {"Trololo"};
coerce _VarcharRange,
from ArrayRef[PositiveOrZeroInt],
via {
my $result;
my @keys = qw(min max);
foreach my $val (reverse @$_) {
my $key = pop @keys // 'bad_range';
$result->{$key} = $val;
}
return $result;
};
has 'my_range' => ( isa => _VarcharRange, is => 'ro', coerce => 1 );
1;
以及相应的测试文件:
!/usr/bin/env perl
use MyTypes qw(_VarcharRange);
my $check = MyTypes->new(
#my_range => [5, 10], # works fine
#my_range => [1, 0], # fails, as expected
#my_range => [0, 1, 2], # fails, as expected
#my_range => [10], # works fine
);
到目前为止一切顺利,但现在我尝试添加_Varchar
类型_VarcharRange
。将其添加到MyTypes.pm
:
subtype _Varchar,
as Parameterizable[Str, _VarcharRange],
where {
my ( $string, $range ) = @_;
my $len = length($string);
return 0 if ($range->{min} && $len < $range->{min});
return 0 if ($range->{max} && $len > $range->{max});
return 1;
},
message { "'$_[0]' length is not within range $_[1]->{min} - $_[1]->{max}" };
has 'my_string' => ( isa => _Varchar[ [1, 10] ], is => 'ro' );
这不起作用。
我所期望的是_VarcharRange
将通过来自[1, 10]
数组引用的强制隐式创建。但看起来我的代码甚至没有继续创建_VarcharRange
,因为我试图直接用_Varchar
参数化我的ArrayRef
。
有没有办法实现我想要的?将数组引用作为参数传递,但具有强制中间类型_VarcharRange
并实际用于参数化。
我不想直接从_Varchar
参数化ArrayRef
,因为它不是非常面向对象的。感觉就像一个范围的独立类型是正确的方式。