package Moose::Util::TypeConstraints;
-use strict;
-use warnings;
-
use Carp ();
use List::MoreUtils qw( all any );
use Scalar::Util qw( blessed reftype );
use Moose::Exporter;
-our $VERSION = '0.73';
+our $VERSION = '0.77';
$VERSION = eval $VERSION;
our $AUTHORITY = 'cpan:STEVAN';
}
sub duck_type {
- my ($type_name, @methods) = @_;
+ my ( $type_name, @methods ) = @_;
if ( ref $type_name eq 'ARRAY' && !@methods ) {
- @methods = @$type_name;
+ @methods = @$type_name;
$type_name = undef;
}
register_type_constraint(
_create_type_constraint(
- $type_name, 'Object',
+ $type_name,
+ 'Object',
sub {
my $obj = $_;
- my @missing_methods = grep { !$obj->can($_) } @methods;
- return ! scalar @missing_methods;
+ return 0 unless all { $obj->can($_) } @methods;
+ return 1;
},
sub {
my $obj = $_;
# these are Class::MOP accessors, so they need inlining
inline_accessors => 1
) for grep { $_->is_mutable }
- map { $_->meta }
+ map { Class::MOP::class_of($_) }
qw(
Moose::Meta::TypeConstraint
Moose::Meta::TypeConstraint::Union
);
type 'Any' => where {1}; # meta-type including all
-type 'Item' => where {1}; # base-type
+subtype 'Item' => as 'Any'; # base-type
subtype 'Undef' => as 'Item' => where { !defined($_) };
subtype 'Defined' => as 'Item' => where { defined($_) };
subtype 'Str' => as 'Value' => where {1} =>
optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
-subtype 'Num' => as 'Value' =>
+subtype 'Num' => as 'Str' =>
where { Scalar::Util::looks_like_number($_) } =>
optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
\&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
subtype 'RoleName' => as 'ClassName' => where {
- ( ( $_->can('meta') || return )->($_) || return )
- ->isa('Moose::Meta::Role');
+ (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
} => optimize_as
\&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
=over 4
-=item B<subtype 'Name' => as 'Parent' => where { } ...>
+=item B<< subtype 'Name' => as 'Parent' => where { } ... >>
This creates a named subtype.
The valid hashref keys are C<as> (the parent), C<where>, C<message>,
and C<optimize_as>.
-=item B<subtype as 'Parent' => where { } ...>
+=item B<< subtype as 'Parent' => where { } ... >>
This creates an unnamed subtype and will return the type
constraint meta-object, which will be an instance of
Creates a type constraint for either C<undef> or something of the
given type.
+=item B<duck_type ($name, @methods)>
+
+This will create a subtype of Object and test to make sure the value
+C<can()> do the methods in C<@methods>.
+
+This is intended as an easy way to accept non-Moose objects that
+provide a certain interface. If you're using Moose classes, we
+recommend that you use a C<requires>-only Role instead.
+
+=item B<duck_type (\@methods)>
+
+If passed an ARRAY reference instead of the C<$name>, C<@methods>
+pair, this will create an unnamed duck type. This can be used in an
+attribute definition like so:
+
+ has 'cache' => (
+ is => 'ro',
+ isa => duck_type( [qw( get_set )] ),
+ );
+
=item B<enum ($name, @values)>
This will create a basic subtype for a given set of strings.