我在Moose课上有以下特性
package myPackage;
use Moose;
has Number => (
is => 'rw',
isa => Num,
);
Run Code Online (Sandbox Code Playgroud)
是否有一个选项与Moose约束此类型浮点数从0到100如果有人试图插入数字不在0 -100的范围,那么值将是undef,如果是,我怎么能实现它?
这似乎按照要求做了......
{
package MyPackage;
use Moose;
use Types::Standard qw( Maybe Num );
use Types::Numbers qw( NumRange );
has n => (
is => 'rw',
isa => (Maybe[ NumRange[0,100] ])->plus_coercions(Num, sub { undef }),
coerce => 1,
);
}
print MyPackage->new( n => 99 )->dump;
print MyPackage->new( n => 100 )->dump;
print MyPackage->new( n => 101 )->dump;
Run Code Online (Sandbox Code Playgroud)
更新:一些解释......
这是0到100之间的数字的类型约束:
NumRange[0,100]
Run Code Online (Sandbox Code Playgroud)
包装它Maybe[...]允许undef被接受为值:
Maybe[ NumRange[0,100] ]
Run Code Online (Sandbox Code Playgroud)
现在我们需要在该表达式返回的类型约束对象上调用一个方法.Maybe[...]->methodname由于->运算符的优先级("它将尝试在arrayref上调用方法,并将结果传递给" Maybe),"显而易见" 将无效.所以我们需要提供一些括号来进行方法调用(Maybe[...])->methodname.
我们将调用的方法是plus_coercions在Type :: Tiny中定义的(Types :: Standard和Types :: Numbers使用的基础类型约束库).这会创建一个新的子类型,Maybe[NumRange[0,100]]但会为其添加一些强制.
我们增加的强制是:
Num, sub { undef }
Run Code Online (Sandbox Code Playgroud)
...这意味着"如果要强制的值是一个数字,则运行此子并使用其输出".在sub中,我们不需要检查被强制的值是否在0..100范围之外,因为只有在值Maybe[NumRange[0,100]]类型约束失败时才会触发强制.
事实上,我们也可以这样表达:
(Maybe[ NumRange[0,100] ])->plus_coercions(Num, 'undef')
Run Code Online (Sandbox Code Playgroud)
...使用一串Perl代码而不是sub.这可能稍微不那么清楚,但可能会稍微快一点,因为它允许Type :: Tiny使用内联代码来玩弄技巧.(通过它我基本上意味着连接Perl代码的各种字符串并将eval它们连接起来,这样它最终会得到一个执行整个检查/强制的子服务器,而不需要调用不同的子服务器来执行检查和强制执行.)
在这种情况下,它不太可能对性能产生任何可察觉的差异,但是如果您想要强制执行此类数字的大量数据,您可能会注意到.
ArrayRef[ (Maybe[NumRange[0,100]])->plus_coercions(Num, 'undef') ]
Run Code Online (Sandbox Code Playgroud)