Using blissful CodeRefs with restrictions like Moose

We use Moose classes that serialize iterators to various output formats. We describe the iterator as an attribute:

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

This has worked well so far, but lately we used Iterator :: Simple to prepare iterators for later consumption. This means that we can write this:

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

And let our serializers accept the iterator class correctly. However, this seems like an incomplete solution.

Moose , ? , Moose:: Util:: TypeConstraints overload:: Overloaded &{}, , - , , Moose.

+5
2

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 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;
+4

All Articles