perl – Moose和constriant类变量

我在Moose课上有以下特性

package myPackage;
 use Moose;

has Number => (
  is  => 'rw',
  isa => Num,

 );

是否有一个选项与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;

更新:一些解释……

这是0到100之间的数字的类型约束:

NumRange[0,100]

用Maybe […]包装它允许将undef作为值接受:

Maybe[ NumRange[0,100] ]

现在我们需要在该表达式返回的类型约束对象上调用一个方法.由于 – >的优先级,“明显的”Maybe […] – > methodname将无效. operator(它会尝试在arrayref上调用该方法,并将结果传递给Maybe).所以我们需要提供一些括号来进行方法调用(Maybe […]) – > methodname.

我们将调用的方法是plus_coercions,在Type::Tiny中定义(Types :: Standard和Types :: Numbers使用的基础类型约束库).这会创建一个新的子类型[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代码的各种字符串并对它们进行评估,这样它最终会得到一个完成检查/强制执行的子程序,而不需要调用不同的子程序来执行检查和强制执行.)

在这种情况下,它不太可能对性能产生任何可察觉的差异,但是如果您想要强制执行此类数字的大量数据,您可能会注意到.

ArrayRef[ (Maybe[NumRange[0,100]])->plus_coercions(Num, 'undef') ]
点赞