我想创建一个基于字符串的类型,它具有较高的长度限制,以及 - 可选的 - 较低的长度限制。即,参数化类型,其中长度范围将是参数。
我在执行中想要什么:使用Type :: Tiny的另一种类型的参数化类型
- 字符串长度范围的单独类型。
- 不使用MooseX ::种类::参数化
- 参数化的直线与数组引用类型的糖,而不是hashref:
- 此:
isa=>Varchar[1, 15]
- 不是这个:
isa=>Varchar[{min=>1, max=>15,}]
- 此:
这就是我到目前为止:
文件MyTypesTiny.pm
package MyTypesTiny;
use strict;
use warnings;
use Type::Library
-base,
-declare => qw(VarcharRange Varchar);
use Type::Utils -all;
use Types::Standard -types;
use MooseX::Types::Common::Numeric qw(PositiveOrZeroInt);
declare VarcharRange,
as HashRef [PositiveOrZeroInt],
where {
return 0 if (grep { $_ ne 'min' && $_ ne 'max' } keys %{$_});
return ($_->{min} <= $_->{max})
if (defined $_->{max} && defined $_->{min});
return 1;
}, message { "$_" };
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;
};
1;
文件test_varchar.pl
#!/usr/bin/env perl
package MyClass;
use Moose;
use MyTypesTiny qw(VarcharRange);
has 'my_range' => (isa=>VarcharRange, is=>'ro', coerce=>1);
package main;
use MyClass;
my $check = MyClass->new(
my_range => [1, 15], # works, as expected
# my_range => [1, 0], # fails, as expected
# my_range => [0, 1, 2], # fails, as expected
);
好吧,VarcharRange工作。 现在我必须添加Varchar本身。而这也正是我得到瞬间探出:
加入MyTypesTiny.pm:
declare Varchar, as Str, where {}, constraint_generator => sub {
# here I have @_ which is an ArrayRef
# and I want to create a VarcharRange object $range from it
# but what exactly should I do?
return sub {
my $len = length($_);
return 0 if ($range->{min} && $len < $range->{min});
return 0 if ($range->{max} && $len > $range->{max});
return 1;
};
};
我的大脑沸腾。我准备好了ArrayRef。我需要的是一个VarcharRange(它基本上是一个HashRef)对象。但是VarcharRange是一种类型 - 一种标记约束和强制规则集合的名称。它本身不对应于一个对象。对象类型是在创建类属性时创建的,但我在这里没有任何类。
你没有放弃,是吗? :D – simbabque
我没有看到'VarcharRange'和'Varchar'之间的连接。 – simbabque
请参阅'Varchar'代码中的注释行。实际上,当我通过ArrayRef参数化'Varchar'时,实际上,我想通过'VarcharRange'(可以从ArrayRef强制)参数化'Varchar'。 – Bob