perl - Moose 和约束类变量

标签 perl moose

我在 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由于 -> 的优先级,将无法工作运算符(它会尝试调用 arrayref 上的方法,并将结果传递给 Maybe )。所以我们需要提供一些括号来做方法调用(Maybe[...])->methodname .

我们将调用的方法是 plus_coercions ,定义于 Type::Tiny (Types::Standard 和 Types::Numbers 使用的底层类型约束库)。这将创建一个新的子类型 Maybe[NumRange[0,100]]但添加了一些强制。

我们添加的强制是:
Num, sub { undef }

...这意味着“如果要强制的值是一个数字,则运行此子程序并使用其输出”。在 sub 中,我们不需要检查被强制转换的值是否在 0..100 范围之外,因为只有当值不符合 Maybe[NumRange[0,100]] 时才会触发强制转换。类型约束。

其实我们也可以这样表达:
(Maybe[ NumRange[0,100] ])->plus_coercions(Num, 'undef')

... 使用一串 Perl 代码而不是子代码。这可能不太清楚,但可能运行得稍微快一点,因为它允许 Type::Tiny 使用内联代码玩花招。 (我基本上是指将各种 Perl 代码字符串和 eval 连接起来,以便最终可以得到一个执行整个检查/强制转换的子程序,而不需要调用不同的子程序来执行检查和强制转换.)

在这种情况下,它不太可能对性能产生任何可察觉的差异,但是如果您有大量想要强制转换的此类数字的数组引用,您可能会注意到。
ArrayRef[ (Maybe[NumRange[0,100]])->plus_coercions(Num, 'undef') ]

关于perl - Moose 和约束类变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20708347/

相关文章:

arrays - Perl - 将变量分配给引用的值

perl - readline 卡在手动 pipe() 上

perl - 这两个关于注释和原型(prototype)的警告在 Perl 中意味着什么?

perl - 已创建类型约束 'XYZ'

perl - Moose:构建器需要一个有时未设置的值(非确定性)

perl - 如何模拟 Moose 对象?

perl - 为什么我可以打开undef?

perl - 如何使用 Time::Piece strptime 解析微秒?

perl - 如何向调用者模块注入(inject)角色?

perl - 如何将 Moose 对象转换为 JSON 以在 Catalyst 中使用?