使用具有Moose类型约束的祝福CodeRef

时间:2012-01-26 17:03:58

标签: perl moose moosex-types

我们使用Moose类将迭代器序列化为各种输出格式。我们将迭代器描述为属性:

has iterator => (
    is => 'ro',
    isa => 'CodeRef',
    required => 1,
);

到目前为止,这个工作正常,但我们最近一直在使用Iterator::Simple来准备迭代器以供以后使用。这意味着我们可以写下这个:

has iterator => (
    is => 'ro',
    isa => 'CodeRef|Iterator::Simple::Iterator',
    required => 1,
);

并允许我们的序列化程序正确接受迭代器类。但是,这似乎是一个不完整的解决方案。

Moose有没有办法指定属性必须可调用的约束?我怀疑可以使用Moose::Util::TypeConstraints并使用&{}上的overload::Overloaded来检查,但我想知道是否有人创建了一个模块来执行此操作,或者是否有穆斯标准的测试方法。

2 个答案:

答案 0 :(得分:4)

CodeRef仅允许未经验证的代码引用。幸运的是,制作自己的类型很容易。

如下所示定义Callable,然后使用它代替CodeRef。它允许以下内容:

  • 无法使用的代码参考。
  • 祝福代码参考。
  • 假装是代码引用的对象(即那些超载&{}的对象)。

use Moose::Util::TypeConstraints;
use overload     qw( );
use Scalar::Util qw( );

subtype 'Callable'
    => as 'Ref'
    => where {
          Scalar::Util::reftype($_) eq 'CODE'
             ||
          Scalar::Util::blessed($_) && overload::Method($_, "&{}")
       }

    # Written such that parent's inline_as needs not be prepended.
    => inline_as {'(
          (Scalar::Util::reftype('.$_[1].') // "") eq 'CODE'
             ||
          Scalar::Util::blessed('.$_[1].') && overload::Method('.$_[1].', "&{}")
       )'};

no Moose::Util::TypeConstraints;

答案 1 :(得分:0)

你知道从Scalar::Util::reftype获得足够的信息吗?