【问题标题】:Moose and constriant class variablesMoose 和约束类变量
【发布时间】:2013-12-20 16:51:56
【问题描述】:

我在 Moose 类上有以下属性

package myPackage;
 use Moose;

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

 );

Moose 是否有一个选项可以将此类型限制为从 0 到 100 的浮点数,如果有人尝试插入不在 0 -100 范围内的数字,那么该值将是 undef,如果是,我该如何实现?

【问题讨论】:

    标签: perl moose


    【解决方案1】:

    这似乎是按要求做的......

    {
      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 并使用它的输出”。在 sub 中,我们不需要检查被强制的值是否在 0..100 范围之外,因为只有当值不符合 Maybe[NumRange[0,100]] 类型约束时才会触发强制。

    其实我们也可以这样表达:

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

    ... 使用 Perl 代码字符串而不是子代码。这可能不太清楚,但运行速度可能会稍微快一些,因为它允许 Type::Tiny 使用内联代码玩技巧。 (我的意思是连接各种 Perl 代码字符串并 evaling 它们,这样它就可以最终得到一个执行整个检查/强制的子程序,而不是需要调用不同的子程序来执行检查和强制.)

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

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

    【讨论】:

      【解决方案2】:

      是的。请参阅 TypeConstraints 文档以及如何强制一个值。

      http://metacpan.org/pod/Moose::Util::TypeConstraints

      【讨论】:

      • 您能否提供一个示例,如果该值不在 0 和 100 之间,如何将其设置为 undef ?谢谢
      • 这个答案可以使用一些额外的细节(比如 how 的例子来做 OP 的要求)。目前基本上只是一个链接,也就是discouraged for a number of reasons
      猜你喜欢
      • 1970-01-01
      • 2016-02-21
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      • 2014-05-23
      • 2021-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多