我想創建一個基於字符串的類型,它具有較高的長度限制,以及 - 可選的 - 較低的長度限制。即,參數化類型,其中長度範圍將是參數。
我在執行中想要什麼:使用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