我对Moose课程有以下特性
package myPackage;
use Moose;
has Number => (
is => 'rw',
isa => Num,
);
Moose有一个选项可以将此类型限制为0到100之间的浮点数,如果有人尝试插入的数字不在0-100范围内,那么该值将是undef,如果是,我该如何实现呢?
答案 0 :(得分:5)
这似乎按照要求行事......
{
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;
更新:一些解释......
这是0到100之间数字的类型约束:
NumRange[0,100]
使用Maybe[...]
对其进行换行,可以接受undef
作为值:
Maybe[ NumRange[0,100] ]
现在我们需要在该表达式返回的类型约束对象上调用一个方法。 "显而易见的" Maybe[...]->methodname
由于->
运算符的优先级而无法工作(它会尝试在arrayref上调用该方法,并将结果传递给Maybe
)。所以我们需要提供一些括号来进行方法调用(Maybe[...])->methodname
。
我们将要调用的方法是plus_coercions
,在Type::Tiny中定义(类型::标准和类型::数字使用的基础类型约束库)。这会创建一个新的Maybe[NumRange[0,100]]
子类型,但会为其添加一些强制。
我们添加的强制是:
Num, sub { undef }
...表示"如果要强制的值是数字,请运行此子并使用其输出"。在sub中,我们不需要检查被强制的值是否在0..100范围之外,因为只有在Maybe[NumRange[0,100]]
类型约束失败时才会触发强制。
事实上,我们也可以这样表达:
(Maybe[ NumRange[0,100] ])->plus_coercions(Num, 'undef')
...使用一串Perl代码而不是sub。这可能稍微不那么清楚,但可能会稍微快一点,因为它允许Type :: Tiny使用内联代码来玩弄技巧。 (通过它我基本上意味着连接Perl代码的各种字符串和eval
它们,这样它最终可以得到一个完成检查/强制的子,而不需要调用不同的子进行检查和强制。)
在这种情况下,它不太可能对性能产生任何可察觉的差异,但如果您想要强制执行大量此类数字,您可能会注意到。
ArrayRef[ (Maybe[NumRange[0,100]])->plus_coercions(Num, 'undef') ]
答案 1 :(得分:-3)
是。请参阅TypeConstraints文档以及如何强制赋值。