Fix bug with multiple class_type statements.
[gitmo/Moose.git] / lib / Moose / Util / TypeConstraints.pm
CommitLineData
a15dff8d 1
2package Moose::Util::TypeConstraints;
3
998a8a25 4use Carp ();
9e856c83 5use List::MoreUtils qw( all any );
9a63faba 6use Scalar::Util qw( blessed reftype );
e606ae5f 7use Moose::Exporter;
a15dff8d 8
d9b40005 9## --------------------------------------------------------
e85d2a5d 10# Prototyped subs must be predeclared because we have a
11# circular dependency with Moose::Meta::Attribute et. al.
12# so in case of us being use'd first the predeclaration
d9b40005 13# ensures the prototypes are in scope when consumers are
14# compiled.
15
d9b40005 16# dah sugah!
180899ed 17sub where (&);
18sub via (&);
19sub message (&);
d9b40005 20sub optimize_as (&);
4e36cf24 21sub inline_as (&);
d9b40005 22
d9b40005 23## --------------------------------------------------------
8c4acc60 24
1fa1a58d 25use Moose::Deprecated;
4e036ee4 26use Moose::Meta::TypeConstraint;
3726f905 27use Moose::Meta::TypeConstraint::Union;
0fbd4b0a 28use Moose::Meta::TypeConstraint::Parameterized;
7e4e1ad4 29use Moose::Meta::TypeConstraint::Parameterizable;
620db045 30use Moose::Meta::TypeConstraint::Class;
31use Moose::Meta::TypeConstraint::Role;
dabed765 32use Moose::Meta::TypeConstraint::Enum;
0a6bff54 33use Moose::Meta::TypeConstraint::DuckType;
2ca63f5d 34use Moose::Meta::TypeCoercion;
3726f905 35use Moose::Meta::TypeCoercion::Union;
22aed3c0 36use Moose::Meta::TypeConstraint::Registry;
4e036ee4 37
e606ae5f 38Moose::Exporter->setup_import_methods(
39 as_is => [
40 qw(
180899ed 41 type subtype class_type role_type maybe_type duck_type
7afaa906 42 as where message optimize_as inline_as
e606ae5f 43 coerce from via
0faea2a8 44 enum union
e606ae5f 45 find_type_constraint
0d29b772 46 register_type_constraint
47 match_on_type )
e606ae5f 48 ],
e606ae5f 49);
a15dff8d 50
d9b40005 51## --------------------------------------------------------
52## type registry and some useful functions for it
53## --------------------------------------------------------
54
22aed3c0 55my $REGISTRY = Moose::Meta::TypeConstraint::Registry->new;
587ae0d2 56
180899ed 57sub get_type_constraint_registry {$REGISTRY}
58sub list_all_type_constraints { keys %{ $REGISTRY->type_constraints } }
59
d9b40005 60sub export_type_constraints_as_functions {
61 my $pkg = caller();
62 no strict 'refs';
180899ed 63 foreach my $constraint ( keys %{ $REGISTRY->type_constraints } ) {
64 my $tc = $REGISTRY->get_type_constraint($constraint)
65 ->_compiled_type_constraint;
66 *{"${pkg}::${constraint}"}
67 = sub { $tc->( $_[0] ) ? 1 : undef }; # the undef is for compat
a0f8153d 68 }
d9b40005 69}
182134e8 70
0c015f1b 71sub create_type_constraint_union {
8ac5be59 72 _create_type_constraint_union(\@_);
182134e8 73}
a15dff8d 74
a46050ae 75sub create_named_type_constraint_union {
76 my $name = shift;
8ac5be59 77 _create_type_constraint_union($name, \@_);
78}
79
80sub _create_type_constraint_union {
81 my $name;
82 $name = shift if @_ > 1;
83 my @tcs = @{ shift() };
84
a46050ae 85 my @type_constraint_names;
86
8ac5be59 87 if ( scalar @tcs == 1 && _detect_type_constraint_union( $tcs[0] ) ) {
88 @type_constraint_names = _parse_type_constraint_union( $tcs[0] );
a46050ae 89 }
90 else {
8ac5be59 91 @type_constraint_names = @tcs;
a46050ae 92 }
93
94 ( scalar @type_constraint_names >= 2 )
95 || __PACKAGE__->_throw_error(
96 "You must pass in at least 2 type names to make a union");
97
98 my @type_constraints = map {
99 find_or_parse_type_constraint($_)
100 || __PACKAGE__->_throw_error(
101 "Could not locate type constraint ($_) for the union");
102 } @type_constraint_names;
103
104 my %options = (
105 type_constraints => \@type_constraints
106 );
107 $options{name} = $name if defined $name;
108
109 return Moose::Meta::TypeConstraint::Union->new(%options);
110}
111
112
0c015f1b 113sub create_parameterized_type_constraint {
d9b40005 114 my $type_constraint_name = shift;
180899ed 115 my ( $base_type, $type_parameter )
116 = _parse_parameterized_type_constraint($type_constraint_name);
e85d2a5d 117
180899ed 118 ( defined $base_type && defined $type_parameter )
119 || __PACKAGE__->_throw_error(
120 "Could not parse type name ($type_constraint_name) correctly");
e85d2a5d 121
180899ed 122 if ( $REGISTRY->has_type_constraint($base_type) ) {
90e78884 123 my $base_type_tc = $REGISTRY->get_type_constraint($base_type);
124 return _create_parameterized_type_constraint(
125 $base_type_tc,
126 $type_parameter
127 );
180899ed 128 }
129 else {
130 __PACKAGE__->_throw_error(
131 "Could not locate the base type ($base_type)");
90e78884 132 }
22aed3c0 133}
134
90e78884 135sub _create_parameterized_type_constraint {
136 my ( $base_type_tc, $type_parameter ) = @_;
137 if ( $base_type_tc->can('parameterize') ) {
138 return $base_type_tc->parameterize($type_parameter);
180899ed 139 }
140 else {
90e78884 141 return Moose::Meta::TypeConstraint::Parameterized->new(
180899ed 142 name => $base_type_tc->name . '[' . $type_parameter . ']',
90e78884 143 parent => $base_type_tc,
180899ed 144 type_parameter =>
145 find_or_create_isa_type_constraint($type_parameter),
90e78884 146 );
147 }
180899ed 148}
90e78884 149
4ab662d6 150#should we also support optimized checks?
0c015f1b 151sub create_class_type_constraint {
620db045 152 my ( $class, $options ) = @_;
153
180899ed 154# too early for this check
155#find_type_constraint("ClassName")->check($class)
156# || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
3fef8ce8 157
fe3eea66 158 my $pkg_defined_in = $options->{package_defined_in} || scalar( caller(1) );
8eddcf9e 159
c8bb956a 160 if (my $type = $REGISTRY->get_type_constraint($class)) {
6f496445 161 if (!($type->isa('Moose::Meta::TypeConstraint::Class') && $type->class eq $class)) {
162 _confess(
163 "The type constraint '$class' has already been created in "
164 . $type->_package_defined_in
165 . " and cannot be created again in "
166 . $pkg_defined_in )
167 }
0f9a0b95 168 else {
169 return $type;
170 }
c8bb956a 171 }
172
620db045 173 my %options = (
8eddcf9e 174 class => $class,
175 name => $class,
176 package_defined_in => $pkg_defined_in,
620db045 177 %{ $options || {} },
4ab662d6 178 );
620db045 179
180 $options{name} ||= "__ANON__";
181
510d13e1 182 my $tc = Moose::Meta::TypeConstraint::Class->new(%options);
183 $REGISTRY->add_type_constraint($tc);
184 return $tc;
3fef8ce8 185}
186
0c015f1b 187sub create_role_type_constraint {
620db045 188 my ( $role, $options ) = @_;
e85d2a5d 189
180899ed 190# too early for this check
191#find_type_constraint("ClassName")->check($class)
192# || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
e85d2a5d 193
fe3eea66 194 my $pkg_defined_in = $options->{package_defined_in} || scalar( caller(1) );
8eddcf9e 195
c8bb956a 196 if (my $type = $REGISTRY->get_type_constraint($role)) {
6f496445 197 if (!($type->isa('Moose::Meta::TypeConstraint::Role') && $type->role eq $role)) {
198 _confess(
199 "The type constraint '$role' has already been created in "
200 . $type->_package_defined_in
201 . " and cannot be created again in "
202 . $pkg_defined_in )
203 }
c8bb956a 204 }
205
620db045 206 my %options = (
8eddcf9e 207 role => $role,
208 name => $role,
209 package_defined_in => $pkg_defined_in,
620db045 210 %{ $options || {} },
211 );
e85d2a5d 212
620db045 213 $options{name} ||= "__ANON__";
214
510d13e1 215 my $tc = Moose::Meta::TypeConstraint::Role->new(%options);
216 $REGISTRY->add_type_constraint($tc);
217 return $tc;
620db045 218}
219
0c015f1b 220sub find_or_create_type_constraint {
620db045 221 my ( $type_constraint_name, $options_for_anon_type ) = @_;
222
180899ed 223 if ( my $constraint
224 = find_or_parse_type_constraint($type_constraint_name) ) {
620db045 225 return $constraint;
d9b40005 226 }
620db045 227 elsif ( defined $options_for_anon_type ) {
180899ed 228
d9b40005 229 # NOTE:
4ab662d6 230 # if there is no $options_for_anon_type
231 # specified, then we assume they don't
f3c4e20e 232 # want to create one, and return nothing.
f3c4e20e 233
d9b40005 234 # otherwise assume that we should create
e85d2a5d 235 # an ANON type with the $options_for_anon_type
d9b40005 236 # options which can be passed in. It should
e85d2a5d 237 # be noted that these don't get registered
d9b40005 238 # so we need to return it.
239 # - SL
240 return Moose::Meta::TypeConstraint->new(
241 name => '__ANON__',
e85d2a5d 242 %{$options_for_anon_type}
d9b40005 243 );
244 }
e85d2a5d 245
620db045 246 return;
247}
248
0c015f1b 249sub find_or_create_isa_type_constraint {
fe3eea66 250 my ($type_constraint_name, $options) = @_;
180899ed 251 find_or_parse_type_constraint($type_constraint_name)
fe3eea66 252 || create_class_type_constraint($type_constraint_name, $options);
620db045 253}
254
0c015f1b 255sub find_or_create_does_type_constraint {
fe3eea66 256 my ($type_constraint_name, $options) = @_;
180899ed 257 find_or_parse_type_constraint($type_constraint_name)
fe3eea66 258 || create_role_type_constraint($type_constraint_name, $options);
620db045 259}
260
0c015f1b 261sub find_or_parse_type_constraint {
eb4c4e82 262 my $type_constraint_name = normalize_type_constraint_name(shift);
620db045 263 my $constraint;
180899ed 264
265 if ( $constraint = find_type_constraint($type_constraint_name) ) {
e606ae5f 266 return $constraint;
180899ed 267 }
268 elsif ( _detect_type_constraint_union($type_constraint_name) ) {
620db045 269 $constraint = create_type_constraint_union($type_constraint_name);
180899ed 270 }
271 elsif ( _detect_parameterized_type_constraint($type_constraint_name) ) {
272 $constraint
273 = create_parameterized_type_constraint($type_constraint_name);
274 }
275 else {
620db045 276 return;
277 }
bb6c8335 278
d9b40005 279 $REGISTRY->add_type_constraint($constraint);
e85d2a5d 280 return $constraint;
d9b40005 281}
22aed3c0 282
eb4c4e82 283sub normalize_type_constraint_name {
84a9c64c 284 my $type_constraint_name = shift;
c8f663b2 285 $type_constraint_name =~ s/\s//g;
eb4c4e82 286 return $type_constraint_name;
287}
288
5f223879 289sub _confess {
290 my $error = shift;
291
292 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
293 Carp::confess($error);
294}
295
22aed3c0 296## --------------------------------------------------------
297## exported functions ...
298## --------------------------------------------------------
299
0c015f1b 300sub find_type_constraint {
eeedfc8a 301 my $type = shift;
302
303 if ( blessed $type and $type->isa("Moose::Meta::TypeConstraint") ) {
304 return $type;
e606ae5f 305 }
306 else {
307 return unless $REGISTRY->has_type_constraint($type);
eeedfc8a 308 return $REGISTRY->get_type_constraint($type);
309 }
310}
22aed3c0 311
0c015f1b 312sub register_type_constraint {
3fef8ce8 313 my $constraint = shift;
180899ed 314 __PACKAGE__->_throw_error("can't register an unnamed type constraint")
315 unless defined $constraint->name;
3fef8ce8 316 $REGISTRY->add_type_constraint($constraint);
dabed765 317 return $constraint;
3fef8ce8 318}
319
7c13858b 320# type constructors
a15dff8d 321
9c27968f 322sub type {
9e856c83 323 my $name = shift;
9a63faba 324
9e856c83 325 my %p = map { %{$_} } @_;
326
180899ed 327 return _create_type_constraint(
328 $name, undef, $p{where}, $p{message},
4e36cf24 329 $p{optimize_as}, $p{inline_as},
180899ed 330 );
a15dff8d 331}
332
9c27968f 333sub subtype {
180899ed 334 if ( @_ == 1 && !ref $_[0] ) {
335 __PACKAGE__->_throw_error(
336 'A subtype cannot consist solely of a name, it must have a parent'
337 );
f75f625d 338 }
339
f6c0c589 340 # The blessed check is mostly to accommodate MooseX::Types, which
341 # uses an object which overloads stringification as a type name.
180899ed 342 my $name = ref $_[0] && !blessed $_[0] ? undef : shift;
9a63faba 343
344 my %p = map { %{$_} } @_;
345
346 # subtype Str => where { ... };
180899ed 347 if ( !exists $p{as} ) {
9e856c83 348 $p{as} = $name;
9a63faba 349 $name = undef;
350 }
351
180899ed 352 return _create_type_constraint(
353 $name, $p{as}, $p{where}, $p{message},
4e36cf24 354 $p{optimize_as}, $p{inline_as},
180899ed 355 );
a15dff8d 356}
357
9c27968f 358sub class_type {
510d13e1 359 create_class_type_constraint(@_);
3fef8ce8 360}
361
620db045 362sub role_type ($;$) {
510d13e1 363 create_role_type_constraint(@_);
620db045 364}
365
1b2c9bda 366sub maybe_type {
367 my ($type_parameter) = @_;
368
28ce1444 369 register_type_constraint(
ed7060d9 370 $REGISTRY->get_type_constraint('Maybe')->parameterize($type_parameter)
28ce1444 371 );
1b2c9bda 372}
373
180899ed 374sub duck_type {
cdacfaf3 375 my ( $type_name, @methods ) = @_;
180899ed 376 if ( ref $type_name eq 'ARRAY' && !@methods ) {
cdacfaf3 377 @methods = @$type_name;
180899ed 378 $type_name = undef;
379 }
bce5d4a5 380 if ( @methods == 1 && ref $methods[0] eq 'ARRAY' ) {
381 @methods = @{ $methods[0] };
382 }
180899ed 383
384 register_type_constraint(
0a6bff54 385 create_duck_type_constraint(
cdacfaf3 386 $type_name,
0a6bff54 387 \@methods,
180899ed 388 )
389 );
390}
391
9c27968f 392sub coerce {
180899ed 393 my ( $type_name, @coercion_map ) = @_;
394 _install_type_coercions( $type_name, \@coercion_map );
182134e8 395}
396
f6c0c589 397# The trick of returning @_ lets us avoid having to specify a
398# prototype. Perl will parse this:
399#
400# subtype 'Foo'
401# => as 'Str'
402# => where { ... }
403#
404# as this:
405#
406# subtype( 'Foo', as( 'Str', where { ... } ) );
407#
69229b40 408# If as() returns all its extra arguments, this just works, and
f6c0c589 409# preserves backwards compatibility.
180899ed 410sub as { { as => shift }, @_ }
9e856c83 411sub where (&) { { where => $_[0] } }
412sub message (&) { { message => $_[0] } }
413sub optimize_as (&) { { optimize_as => $_[0] } }
4e36cf24 414sub inline_as (&) { { inline_as => $_[0] } }
8ecb1fa0 415
9a63faba 416sub from {@_}
417sub via (&) { $_[0] }
a15dff8d 418
9c27968f 419sub enum {
180899ed 420 my ( $type_name, @values ) = @_;
421
4ab662d6 422 # NOTE:
423 # if only an array-ref is passed then
9f4334a1 424 # you get an anon-enum
425 # - SL
f6af1028 426 if ( ref $type_name eq 'ARRAY' ) {
427 @values == 0
428 || __PACKAGE__->_throw_error("enum called with an array reference and additional arguments. Did you mean to parenthesize the enum call's parameters?");
429
9f4334a1 430 @values = @$type_name;
431 $type_name = undef;
432 }
bce5d4a5 433 if ( @values == 1 && ref $values[0] eq 'ARRAY' ) {
434 @values = @{ $values[0] };
435 }
dabed765 436
437 register_type_constraint(
438 create_enum_type_constraint(
439 $type_name,
440 \@values,
441 )
442 );
443}
444
0faea2a8 445sub union {
446 my ( $type_name, @constraints ) = @_;
447 if ( ref $type_name eq 'ARRAY' ) {
448 @constraints == 0
449 || __PACKAGE__->_throw_error("union called with an array reference and additional arguments.");
450 @constraints = @$type_name;
451 $type_name = undef;
452 }
453 if ( @constraints == 1 && ref $constraints[0] eq 'ARRAY' ) {
454 @constraints = @{ $constraints[0] };
455 }
0faea2a8 456 if ( defined $type_name ) {
a46050ae 457 return register_type_constraint(
458 create_named_type_constraint_union( $type_name, @constraints )
459 );
0faea2a8 460 }
a46050ae 461 return create_type_constraint_union( @constraints );
0faea2a8 462}
463
0c015f1b 464sub create_enum_type_constraint {
dabed765 465 my ( $type_name, $values ) = @_;
e606ae5f 466
dabed765 467 Moose::Meta::TypeConstraint::Enum->new(
180899ed 468 name => $type_name || '__ANON__',
dabed765 469 values => $values,
a0f8153d 470 );
fcec2383 471}
472
0a6bff54 473sub create_duck_type_constraint {
474 my ( $type_name, $methods ) = @_;
475
476 Moose::Meta::TypeConstraint::DuckType->new(
477 name => $type_name || '__ANON__',
478 methods => $methods,
479 );
480}
481
0d29b772 482sub match_on_type {
483 my ($to_match, @cases) = @_;
484 my $default;
485 if (@cases % 2 != 0) {
486 $default = pop @cases;
487 (ref $default eq 'CODE')
488 || __PACKAGE__->_throw_error("Default case must be a CODE ref, not $default");
489 }
490 while (@cases) {
491 my ($type, $action) = splice @cases, 0, 2;
492
493 unless (blessed $type && $type->isa('Moose::Meta::TypeConstraint')) {
494 $type = find_or_parse_type_constraint($type)
495 || __PACKAGE__->_throw_error("Cannot find or parse the type '$type'")
496 }
497
498 (ref $action eq 'CODE')
499 || __PACKAGE__->_throw_error("Match action must be a CODE ref, not $action");
500
501 if ($type->check($to_match)) {
502 local $_ = $to_match;
503 return $action->($to_match);
504 }
505 }
1d39d709 506 (defined $default)
507 || __PACKAGE__->_throw_error("No cases matched for $to_match");
0d29b772 508 {
509 local $_ = $to_match;
1d39d709 510 return $default->($to_match);
0d29b772 511 }
512}
513
514
d9b40005 515## --------------------------------------------------------
516## desugaring functions ...
517## --------------------------------------------------------
518
e85d2a5d 519sub _create_type_constraint ($$$;$$) {
9a63faba 520 my $name = shift;
521 my $parent = shift;
522 my $check = shift;
523 my $message = shift;
524 my $optimized = shift;
4e36cf24 525 my $inlined = shift;
d9b40005 526
9a63faba 527 my $pkg_defined_in = scalar( caller(1) );
e85d2a5d 528
1da6728b 529 if ( defined $name ) {
d9b40005 530 my $type = $REGISTRY->get_type_constraint($name);
e85d2a5d 531
5f223879 532 ( $type->_package_defined_in eq $pkg_defined_in )
533 || _confess(
534 "The type constraint '$name' has already been created in "
535 . $type->_package_defined_in
536 . " and cannot be created again in "
537 . $pkg_defined_in )
538 if defined $type;
eee1a213 539
540 $name =~ /^[\w:\.]+$/
541 or die qq{$name contains invalid characters for a type name.}
33c8a6d0 542 . qq{ Names can contain alphanumeric character, ":", and "."\n};
e85d2a5d 543 }
1da6728b 544
9ceb576e 545 my %opts = (
9a63faba 546 name => $name,
d9b40005 547 package_defined_in => $pkg_defined_in,
e85d2a5d 548
1da6728b 549 ( $check ? ( constraint => $check ) : () ),
550 ( $message ? ( message => $message ) : () ),
551 ( $optimized ? ( optimized => $optimized ) : () ),
4e36cf24 552 ( $inlined ? ( inlined => $inlined ) : () ),
d9b40005 553 );
1da6728b 554
9ceb576e 555 my $constraint;
180899ed 556 if (
557 defined $parent
1da6728b 558 and $parent
180899ed 559 = blessed $parent
560 ? $parent
561 : find_or_create_isa_type_constraint($parent)
562 ) {
85a9908f 563 $constraint = $parent->create_child_type(%opts);
1da6728b 564 }
565 else {
566 $constraint = Moose::Meta::TypeConstraint->new(%opts);
4ab662d6 567 }
d9b40005 568
569 $REGISTRY->add_type_constraint($constraint)
570 if defined $name;
571
572 return $constraint;
573}
574
e85d2a5d 575sub _install_type_coercions ($$) {
180899ed 576 my ( $type_name, $coercion_map ) = @_;
e606ae5f 577 my $type = find_type_constraint($type_name);
180899ed 578 ( defined $type )
579 || __PACKAGE__->_throw_error(
a885c019 580 "Cannot find type '$type_name', perhaps you forgot to load it");
180899ed 581 if ( $type->has_coercion ) {
41e007e4 582 $type->coercion->add_type_coercions(@$coercion_map);
583 }
584 else {
585 my $type_coercion = Moose::Meta::TypeCoercion->new(
586 type_coercion_map => $coercion_map,
587 type_constraint => $type
588 );
589 $type->coercion($type_coercion);
590 }
d9b40005 591}
592
593## --------------------------------------------------------
f1917f58 594## type notation parsing ...
595## --------------------------------------------------------
596
597{
180899ed 598
e85d2a5d 599 # All I have to say is mugwump++ cause I know
600 # do not even have enough regexp-fu to be able
601 # to have written this (I can only barely
f1917f58 602 # understand it as it is)
e85d2a5d 603 # - SL
604
f1917f58 605 use re "eval";
606
eee1a213 607 my $valid_chars = qr{[\w:\.]};
68d5a469 608 my $type_atom = qr{ (?>$valid_chars+) }x;
68113f48 609 my $ws = qr{ (?>\s*) }x;
610 my $op_union = qr{ $ws \| $ws }x;
611
612 my ($type, $type_capture_parts, $type_with_parameter, $union, $any);
613 if (Class::MOP::IS_RUNNING_ON_5_10) {
614 my $type_pattern
615 = q{ (?&type_atom) (?: \[ (?&ws) (?&any) (?&ws) \] )? };
616 my $type_capture_parts_pattern
617 = q{ ((?&type_atom)) (?: \[ (?&ws) ((?&any)) (?&ws) \] )? };
618 my $type_with_parameter_pattern
619 = q{ (?&type_atom) \[ (?&ws) (?&any) (?&ws) \] };
620 my $union_pattern
621 = q{ (?&type) (?> (?: (?&op_union) (?&type) )+ ) };
622 my $any_pattern
623 = q{ (?&type) | (?&union) };
624
625 my $defines = qr{(?(DEFINE)
626 (?<valid_chars> $valid_chars)
627 (?<type_atom> $type_atom)
628 (?<ws> $ws)
629 (?<op_union> $op_union)
630 (?<type> $type_pattern)
631 (?<type_capture_parts> $type_capture_parts_pattern)
632 (?<type_with_parameter> $type_with_parameter_pattern)
633 (?<union> $union_pattern)
634 (?<any> $any_pattern)
635 )}x;
636
637 $type = qr{ $type_pattern $defines }x;
638 $type_capture_parts = qr{ $type_capture_parts_pattern $defines }x;
639 $type_with_parameter = qr{ $type_with_parameter_pattern $defines }x;
640 $union = qr{ $union_pattern $defines }x;
641 $any = qr{ $any_pattern $defines }x;
642 }
643 else {
644 $type
645 = qr{ $type_atom (?: \[ $ws (??{$any}) $ws \] )? }x;
646 $type_capture_parts
647 = qr{ ($type_atom) (?: \[ $ws ((??{$any})) $ws \] )? }x;
648 $type_with_parameter
649 = qr{ $type_atom \[ $ws (??{$any}) $ws \] }x;
650 $union
651 = qr{ $type (?> (?: $op_union $type )+ ) }x;
652 $any
653 = qr{ $type | $union }x;
654 }
f1917f58 655
f1917f58 656
0fbd4b0a 657 sub _parse_parameterized_type_constraint {
180899ed 658 { no warnings 'void'; $any; } # force capture of interpolated lexical
84a9c64c 659 $_[0] =~ m{ $type_capture_parts }x;
180899ed 660 return ( $1, $2 );
f1917f58 661 }
662
0fbd4b0a 663 sub _detect_parameterized_type_constraint {
180899ed 664 { no warnings 'void'; $any; } # force capture of interpolated lexical
e85d2a5d 665 $_[0] =~ m{ ^ $type_with_parameter $ }x;
f1917f58 666 }
667
668 sub _parse_type_constraint_union {
180899ed 669 { no warnings 'void'; $any; } # force capture of interpolated lexical
e85d2a5d 670 my $given = shift;
671 my @rv;
672 while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
82a5b1a7 673 push @rv => $1;
e85d2a5d 674 }
180899ed 675 ( pos($given) eq length($given) )
676 || __PACKAGE__->_throw_error( "'$given' didn't parse (parse-pos="
677 . pos($given)
678 . " and str-length="
679 . length($given)
680 . ")" );
e85d2a5d 681 @rv;
f1917f58 682 }
683
684 sub _detect_type_constraint_union {
180899ed 685 { no warnings 'void'; $any; } # force capture of interpolated lexical
e85d2a5d 686 $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
f1917f58 687 }
688}
689
690## --------------------------------------------------------
d9b40005 691# define some basic built-in types
692## --------------------------------------------------------
a15dff8d 693
06d02aac 694# By making these classes immutable before creating all the types in
695# Moose::Util::TypeConstraints::Builtin , we avoid repeatedly calling the slow
696# MOP-based accessors.
3cae4250 697$_->make_immutable(
698 inline_constructor => 1,
699 constructor_name => "_new",
700
701 # these are Class::MOP accessors, so they need inlining
702 inline_accessors => 1
703 ) for grep { $_->is_mutable }
37edf27e 704 map { Class::MOP::class_of($_) }
3cae4250 705 qw(
706 Moose::Meta::TypeConstraint
707 Moose::Meta::TypeConstraint::Union
708 Moose::Meta::TypeConstraint::Parameterized
709 Moose::Meta::TypeConstraint::Parameterizable
710 Moose::Meta::TypeConstraint::Class
711 Moose::Meta::TypeConstraint::Role
712 Moose::Meta::TypeConstraint::Enum
0a6bff54 713 Moose::Meta::TypeConstraint::DuckType
3cae4250 714 Moose::Meta::TypeConstraint::Registry
715);
716
06d02aac 717require Moose::Util::TypeConstraints::Builtins;
718Moose::Util::TypeConstraints::Builtins::define_builtins($REGISTRY);
7e4e1ad4 719
180899ed 720my @PARAMETERIZABLE_TYPES
2c29c0e7 721 = map { $REGISTRY->get_type_constraint($_) } qw[ScalarRef ArrayRef HashRef Maybe];
180899ed 722
723sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES}
7e4e1ad4 724
4ab662d6 725sub add_parameterizable_type {
7e4e1ad4 726 my $type = shift;
180899ed 727 ( blessed $type
728 && $type->isa('Moose::Meta::TypeConstraint::Parameterizable') )
729 || __PACKAGE__->_throw_error(
730 "Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type"
731 );
7e4e1ad4 732 push @PARAMETERIZABLE_TYPES => $type;
4ab662d6 733}
7e4e1ad4 734
735## --------------------------------------------------------
d9b40005 736# end of built-in types ...
737## --------------------------------------------------------
738
943596a6 739{
740 my @BUILTINS = list_all_type_constraints();
180899ed 741 sub list_all_builtin_type_constraints {@BUILTINS}
943596a6 742}
743
6ea98933 744sub _throw_error {
6b83828f 745 shift;
6ea98933 746 require Moose;
747 unshift @_, 'Moose';
748 goto &Moose::throw_error;
749}
750
a15dff8d 7511;
752
ad46f524 753# ABSTRACT: Type constraint system for Moose
754
a15dff8d 755__END__
756
757=pod
758
a15dff8d 759=head1 SYNOPSIS
760
761 use Moose::Util::TypeConstraints;
762
04eec387 763 subtype 'Natural',
764 as 'Int',
765 where { $_ > 0 };
e85d2a5d 766
04eec387 767 subtype 'NaturalLessThanTen',
768 as 'Natural',
769 where { $_ < 10 },
770 message { "This number ($_) is not less than ten!" };
e85d2a5d 771
04eec387 772 coerce 'Num',
773 from 'Str',
774 via { 0+$_ };
e85d2a5d 775
00954dd1 776 class_type 'DateTimeClass', { class => 'DateTime' };
83aa5247 777
778 role_type 'Barks', { role => 'Some::Library::Role::Barks' };
779
04eec387 780 enum 'RGBColors', [qw(red green blue)];
a15dff8d 781
74dccf76 782 union 'StringOrArray', [qw( String Array )];
783
e7fcb7b2 784 no Moose::Util::TypeConstraints;
785
a15dff8d 786=head1 DESCRIPTION
787
e85d2a5d 788This module provides Moose with the ability to create custom type
6549b0d1 789constraints to be used in attribute definition.
e522431d 790
6ba6d68c 791=head2 Important Caveat
792
e85d2a5d 793This is B<NOT> a type system for Perl 5. These are type constraints,
794and they are not used by Moose unless you tell it to. No type
e7fcb7b2 795inference is performed, expressions are not typed, etc. etc. etc.
6ba6d68c 796
e7fcb7b2 797A type constraint is at heart a small "check if a value is valid"
798function. A constraint can be associated with an attribute. This
799simplifies parameter validation, and makes your code clearer to read,
800because you can refer to constraints by name.
6ba6d68c 801
2c0cbef7 802=head2 Slightly Less Important Caveat
803
e7fcb7b2 804It is B<always> a good idea to quote your type names.
004222dc 805
e7fcb7b2 806This prevents Perl from trying to execute the call as an indirect
807object call. This can be an issue when you have a subtype with the
808same name as a valid class.
2c0cbef7 809
e7fcb7b2 810For instance:
e85d2a5d 811
2c0cbef7 812 subtype DateTime => as Object => where { $_->isa('DateTime') };
813
e7fcb7b2 814will I<just work>, while this:
2c0cbef7 815
816 use DateTime;
817 subtype DateTime => as Object => where { $_->isa('DateTime') };
818
e85d2a5d 819will fail silently and cause many headaches. The simple way to solve
820this, as well as future proof your subtypes from classes which have
e7fcb7b2 821yet to have been created, is to quote the type name:
2c0cbef7 822
823 use DateTime;
04eec387 824 subtype 'DateTime', as 'Object', where { $_->isa('DateTime') };
2c0cbef7 825
6ba6d68c 826=head2 Default Type Constraints
e522431d 827
e606ae5f 828This module also provides a simple hierarchy for Perl 5 types, here is
004222dc 829that hierarchy represented visually.
e522431d 830
831 Any
e85d2a5d 832 Item
5a4c5493 833 Bool
7e4e1ad4 834 Maybe[`a]
f65cb534 835 Undef
836 Defined
5a4c5493 837 Value
5a4c5493 838 Str
f1bbe1e1 839 Num
840 Int
fcb5b0cd 841 ClassName
842 RoleName
5a4c5493 843 Ref
2c29c0e7 844 ScalarRef[`a]
7e4e1ad4 845 ArrayRef[`a]
846 HashRef[`a]
5a4c5493 847 CodeRef
848 RegexpRef
3f7376b0 849 GlobRef
94ab1609 850 FileHandle
e85d2a5d 851 Object
e522431d 852
4ab662d6 853B<NOTE:> Any type followed by a type parameter C<[`a]> can be
7e4e1ad4 854parameterized, this means you can say:
855
757e07ef 856 ArrayRef[Int] # an array of integers
7e4e1ad4 857 HashRef[CodeRef] # a hash of str to CODE ref mappings
2c29c0e7 858 ScalarRef[Int] # a reference to an integer
7e4e1ad4 859 Maybe[Str] # value may be a string, may be undefined
860
4e8a0f64 861If Moose finds a name in brackets that it does not recognize as an
862existing type, it assumes that this is a class name, for example
863C<ArrayRef[DateTime]>.
864
e7fcb7b2 865B<NOTE:> Unless you parameterize a type, then it is invalid to include
866the square brackets. I.e. C<ArrayRef[]> will be treated as a new type
867name, I<not> as a parameterization of C<ArrayRef>.
e606ae5f 868
4ab662d6 869B<NOTE:> The C<Undef> type constraint for the most part works
870correctly now, but edge cases may still exist, please use it
6549b0d1 871sparingly.
703e92fb 872
7e4e1ad4 873B<NOTE:> The C<ClassName> type constraint does a complex package
e7fcb7b2 874existence check. This means that your class B<must> be loaded for this
875type constraint to pass.
9af1d28b 876
e7fcb7b2 877B<NOTE:> The C<RoleName> constraint checks a string is a I<package
4831e2de 878name> which is a role, like C<'MyApp::Role::Comparable'>.
ed87d4fd 879
e606ae5f 880=head2 Type Constraint Naming
004222dc 881
eee1a213 882Type name declared via this module can only contain alphanumeric
883characters, colons (:), and periods (.).
884
e606ae5f 885Since the types created by this module are global, it is suggested
886that you namespace your types just as you would namespace your
e7fcb7b2 887modules. So instead of creating a I<Color> type for your
888B<My::Graphics> module, you would call the type
889I<My::Graphics::Types::Color> instead.
004222dc 890
703e92fb 891=head2 Use with Other Constraint Modules
892
e7fcb7b2 893This module can play nicely with other constraint modules with some
894slight tweaking. The C<where> clause in types is expected to be a
69229b40 895C<CODE> reference which checks its first argument and returns a
e7fcb7b2 896boolean. Since most constraint modules work in a similar way, it
897should be simple to adapt them to work with Moose.
703e92fb 898
e85d2a5d 899For instance, this is how you could use it with
900L<Declare::Constraints::Simple> to declare a completely new type.
703e92fb 901
9e856c83 902 type 'HashOfArrayOfObjects',
04eec387 903 where {
904 IsHashRef(
905 -keys => HasLength,
906 -values => IsArrayRef(IsObject)
907 )->(@_);
908 };
703e92fb 909
2c739d1a 910For more examples see the F<t/examples/example_w_DCS.t> test
e7fcb7b2 911file.
703e92fb 912
69229b40 913Here is an example of using L<Test::Deep> and its non-test
e85d2a5d 914related C<eq_deeply> function.
703e92fb 915
04eec387 916 type 'ArrayOfHashOfBarsAndRandomNumbers',
917 where {
e85d2a5d 918 eq_deeply($_,
703e92fb 919 array_each(subhashof({
920 bar => isa('Bar'),
921 random_number => ignore()
e85d2a5d 922 })))
703e92fb 923 };
924
e606ae5f 925For a complete example see the
2c739d1a 926F<t/examples/example_w_TestDeep.t> test file.
e85d2a5d 927
32549612 928=head2 Error messages
929
930Type constraints can also specify custom error messages, for when they fail to
931validate. This is provided as just another coderef, which receives the invalid
932value in C<$_>, as in:
933
934 subtype 'PositiveInt',
935 as 'Int',
936 where { $_ > 0 },
937 message { "$_ is not a positive integer!" };
938
939If no message is specified, a default message will be used, which indicates
940which type constraint was being used and what value failed. If
941L<Devel::PartialDump> (version 0.14 or higher) is installed, it will be used to
942display the invalid value, otherwise it will just be printed as is.
943
a15dff8d 944=head1 FUNCTIONS
945
946=head2 Type Constraint Constructors
947
e7fcb7b2 948The following functions are used to create type constraints. They
949will also register the type constraints your create in a global
950registry that is used to look types up by name.
a15dff8d 951
cec39889 952See the L</SYNOPSIS> for an example of how to use these.
a15dff8d 953
6ba6d68c 954=over 4
a15dff8d 955
04eec387 956=item B<< subtype 'Name', as 'Parent', where { } ... >>
182134e8 957
e85d2a5d 958This creates a named subtype.
d6e2d9a1 959
dba9208a 960If you provide a parent that Moose does not recognize, it will
961automatically create a new class type constraint for this name.
962
9e856c83 963When creating a named type, the C<subtype> function should either be
964called with the sugar helpers (C<where>, C<message>, etc), or with a
965name and a hashref of parameters:
966
967 subtype( 'Foo', { where => ..., message => ... } );
968
969The valid hashref keys are C<as> (the parent), C<where>, C<message>,
970and C<optimize_as>.
9a63faba 971
04eec387 972=item B<< subtype as 'Parent', where { } ... >>
182134e8 973
e85d2a5d 974This creates an unnamed subtype and will return the type
975constraint meta-object, which will be an instance of
976L<Moose::Meta::TypeConstraint>.
a15dff8d 977
9e856c83 978When creating an anonymous type, the C<subtype> function should either
979be called with the sugar helpers (C<where>, C<message>, etc), or with
980just a hashref of parameters:
981
982 subtype( { where => ..., message => ... } );
983
620db045 984=item B<class_type ($class, ?$options)>
3fef8ce8 985
ed87d4fd 986Creates a new subtype of C<Object> with the name C<$class> and the
987metaclass L<Moose::Meta::TypeConstraint::Class>.
3fef8ce8 988
83aa5247 989 # Create a type called 'Box' which tests for objects which ->isa('Box')
990 class_type 'Box';
991
00954dd1 992By default, the name of the type and the name of the class are the same, but
993you can specify both separately.
83aa5247 994
995 # Create a type called 'Box' which tests for objects which ->isa('ObjectLibrary::Box');
996 class_type 'Box', { class => 'ObjectLibrary::Box' };
997
620db045 998=item B<role_type ($role, ?$options)>
999
ed87d4fd 1000Creates a C<Role> type constraint with the name C<$role> and the
1001metaclass L<Moose::Meta::TypeConstraint::Role>.
620db045 1002
83aa5247 1003 # Create a type called 'Walks' which tests for objects which ->does('Walks')
1004 role_type 'Walks';
1005
00954dd1 1006By default, the name of the type and the name of the role are the same, but
1007you can specify both separately.
83aa5247 1008
1009 # Create a type called 'Walks' which tests for objects which ->does('MooseX::Role::Walks');
1010 role_type 'Walks', { role => 'MooseX::Role::Walks' };
1011
1b2c9bda 1012=item B<maybe_type ($type)>
1013
1014Creates a type constraint for either C<undef> or something of the
1015given type.
1016
bce5d4a5 1017=item B<duck_type ($name, \@methods)>
e451e855 1018
88b68372 1019This will create a subtype of Object and test to make sure the value
bce5d4a5 1020C<can()> do the methods in C<\@methods>.
88b68372 1021
1022This is intended as an easy way to accept non-Moose objects that
1023provide a certain interface. If you're using Moose classes, we
1024recommend that you use a C<requires>-only Role instead.
e451e855 1025
1026=item B<duck_type (\@methods)>
1027
bce5d4a5 1028If passed an ARRAY reference as the only parameter instead of the
1029C<$name>, C<\@methods> pair, this will create an unnamed duck type.
1030This can be used in an attribute definition like so:
e451e855 1031
88b68372 1032 has 'cache' => (
1033 is => 'ro',
1034 isa => duck_type( [qw( get_set )] ),
1035 );
e451e855 1036
bce5d4a5 1037=item B<enum ($name, \@values)>
fcec2383 1038
e85d2a5d 1039This will create a basic subtype for a given set of strings.
1040The resulting constraint will be a subtype of C<Str> and
bce5d4a5 1041will match any of the items in C<\@values>. It is case sensitive.
cec39889 1042See the L</SYNOPSIS> for a simple example.
2c0cbef7 1043
6549b0d1 1044B<NOTE:> This is not a true proper enum type, it is simply
1045a convenient constraint builder.
2c0cbef7 1046
9f4334a1 1047=item B<enum (\@values)>
1048
bce5d4a5 1049If passed an ARRAY reference as the only parameter instead of the
1050C<$name>, C<\@values> pair, this will create an unnamed enum. This
1051can then be used in an attribute definition like so:
9f4334a1 1052
1053 has 'sort_order' => (
1054 is => 'ro',
4ab662d6 1055 isa => enum([qw[ ascending descending ]]),
9f4334a1 1056 );
1057
74dccf76 1058=item B<union ($name, \@constraints)>
1059
1060This will create a basic subtype where any of the provided constraints
1061may match in order to satisfy this constraint.
1062
1063=item B<union (\@constraints)>
1064
1065If passed an ARRAY reference as the only parameter instead of the
1066C<$name>, C<\@constraints> pair, this will create an unnamed union.
1067This can then be used in an attribute definition like so:
1068
1069 has 'items' => (
1070 is => 'ro',
1071 isa => union([qw[ Str ArrayRef ]]),
1072 );
1073
1074This is similar to the existing string union:
1075
1076 isa => 'Str|ArrayRef'
1077
1078except that it supports anonymous elements as child constraints:
1079
1080 has 'color' => (
1081 isa => 'ro',
1082 isa => union([ 'Int', enum([qw[ red green blue ]]) ]),
1083 );
1084
e7fcb7b2 1085=item B<as 'Parent'>
a15dff8d 1086
6ba6d68c 1087This is just sugar for the type constraint construction syntax.
a15dff8d 1088
e7fcb7b2 1089It takes a single argument, which is the name of a parent type.
1090
1091=item B<where { ... }>
a15dff8d 1092
6ba6d68c 1093This is just sugar for the type constraint construction syntax.
76d37e5a 1094
e7fcb7b2 1095It takes a subroutine reference as an argument. When the type
1096constraint is tested, the reference is run with the value to be tested
1097in C<$_>. This reference should return true or false to indicate
1098whether or not the constraint check passed.
e606ae5f 1099
e7fcb7b2 1100=item B<message { ... }>
76d37e5a 1101
1102This is just sugar for the type constraint construction syntax.
a15dff8d 1103
e7fcb7b2 1104It takes a subroutine reference as an argument. When the type
1105constraint fails, then the code block is run with the value provided
1106in C<$_>. This reference should return a string, which will be used in
1107the text of the exception thrown.
e606ae5f 1108
7142d232 1109=item B<inline_as { ... }>
1110
1111This can be used to define a "hand optimized" inlinable version of your type
1112constraint.
1113
1114You provide a subroutine which will be called I<as a method> on a
1115L<Moose::Meta::TypeConstraint> object. It will receive a single parameter, the
1116name of the variable to check, typically something like C<"$_"> or C<"$_[0]">.
1117
1118The subroutine should return a code string suitable for inlining. You can
297899d1 1119assume that the check will be wrapped in parentheses when it is inlined.
7142d232 1120
01062d8a 1121The inlined code should include any checks that your type's parent types
c25e79e8 1122do. If your parent type constraint defines its own inlining, you can simply use
6054adaf 1123that to avoid repeating code. For example, here is the inlining code for the
1124C<Value> type, which is a subtype of C<Defined>:
0578d5ce 1125
1126 sub {
1127 $_[0]->parent()->_inline_check($_[1])
1128 . ' && !ref(' . $_[1] . ')'
1129 }
7142d232 1130
e7fcb7b2 1131=item B<optimize_as { ... }>
8ecb1fa0 1132
7142d232 1133B<This feature is deprecated, use C<inline_as> instead.>
1134
e85d2a5d 1135This can be used to define a "hand optimized" version of your
d44714be 1136type constraint which can be used to avoid traversing a subtype
6549b0d1 1137constraint hierarchy.
d44714be 1138
b0f8f0ec 1139B<NOTE:> You should only use this if you know what you are doing.
1140All the built in types use this, so your subtypes (assuming they
d44714be 1141are shallow) will not likely need to use this.
1142
04eec387 1143=item B<< type 'Name', where { } ... >>
e7fcb7b2 1144
1145This creates a base type, which has no parent.
1146
1147The C<type> function should either be called with the sugar helpers
1148(C<where>, C<message>, etc), or with a name and a hashref of
1149parameters:
1150
1151 type( 'Foo', { where => ..., message => ... } );
1152
7142d232 1153The valid hashref keys are C<where>, C<message>, and C<inlined_as>.
e7fcb7b2 1154
6ba6d68c 1155=back
a15dff8d 1156
0d29b772 1157=head2 Type Constraint Utilities
1158
1159=over 4
1160
1161=item B<< match_on_type $value => ( $type => \&action, ... ?\&default ) >>
1162
1a15f4a8 1163This is a utility function for doing simple type based dispatching similar to
2ae1457e 1164match/case in OCaml and case/of in Haskell. It is not as featureful as those
1a15f4a8 1165languages, nor does not it support any kind of automatic destructuring
1166bind. Here is a simple Perl pretty printer dispatching over the core Moose
1167types.
0d29b772 1168
1169 sub ppprint {
1170 my $x = shift;
1a15f4a8 1171 match_on_type $x => (
1172 HashRef => sub {
0d29b772 1173 my $hash = shift;
1a15f4a8 1174 '{ '
1175 . (
1176 join ", " => map { $_ . ' => ' . ppprint( $hash->{$_} ) }
1177 sort keys %$hash
1178 ) . ' }';
1179 },
1180 ArrayRef => sub {
0d29b772 1181 my $array = shift;
1a15f4a8 1182 '[ ' . ( join ", " => map { ppprint($_) } @$array ) . ' ]';
1183 },
1184 CodeRef => sub {'sub { ... }'},
1185 RegexpRef => sub { 'qr/' . $_ . '/' },
1186 GlobRef => sub { '*' . B::svref_2object($_)->NAME },
0d29b772 1187 Object => sub { $_->can('to_string') ? $_->to_string : $_ },
1a15f4a8 1188 ScalarRef => sub { '\\' . ppprint( ${$_} ) },
1189 Num => sub {$_},
1190 Str => sub { '"' . $_ . '"' },
1191 Undef => sub {'undef'},
1192 => sub { die "I don't know what $_ is" }
1193 );
0d29b772 1194 }
1195
e7597637 1196Or a simple JSON serializer:
1197
1198 sub to_json {
1199 my $x = shift;
1a15f4a8 1200 match_on_type $x => (
1201 HashRef => sub {
e7597637 1202 my $hash = shift;
1a15f4a8 1203 '{ '
1204 . (
1205 join ", " =>
1206 map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
1207 sort keys %$hash
1208 ) . ' }';
1209 },
1210 ArrayRef => sub {
e7597637 1211 my $array = shift;
1a15f4a8 1212 '[ ' . ( join ", " => map { to_json($_) } @$array ) . ' ]';
1213 },
1214 Num => sub {$_},
1215 Str => sub { '"' . $_ . '"' },
1216 Undef => sub {'null'},
1217 => sub { die "$_ is not acceptable json type" }
1218 );
e7597637 1219 }
1220
1a15f4a8 1221The matcher is done by mapping a C<$type> to an C<\&action>. The C<$type> can
1222be either a string type or a L<Moose::Meta::TypeConstraint> object, and
1223C<\&action> is a subroutine reference. This function will dispatch on the
1224first match for C<$value>. It is possible to have a catch-all by providing an
1225additional subroutine reference as the final argument to C<match_on_type>.
0d29b772 1226
1227=back
1228
6ba6d68c 1229=head2 Type Coercion Constructors
a15dff8d 1230
e7fcb7b2 1231You can define coercions for type constraints, which allow you to
1232automatically transform values to something valid for the type
1233constraint. If you ask your accessor to coerce, then Moose will run
1234the type-coercion code first, followed by the type constraint
1235check. This feature should be used carefully as it is very powerful
1236and could easily take off a limb if you are not careful.
a15dff8d 1237
cec39889 1238See the L</SYNOPSIS> for an example of how to use these.
a15dff8d 1239
6ba6d68c 1240=over 4
a15dff8d 1241
04eec387 1242=item B<< coerce 'Name', from 'OtherName', via { ... } >>
a15dff8d 1243
e7fcb7b2 1244This defines a coercion from one type to another. The C<Name> argument
1245is the type you are coercing I<to>.
1246
f55dd47f 1247To define multiple coercions, supply more sets of from/via pairs:
1248
04eec387 1249 coerce 'Name',
1250 from 'OtherName', via { ... },
1251 from 'ThirdName', via { ... };
f55dd47f 1252
e7fcb7b2 1253=item B<from 'OtherName'>
a15dff8d 1254
6ba6d68c 1255This is just sugar for the type coercion construction syntax.
1256
e7fcb7b2 1257It takes a single type name (or type object), which is the type being
1258coerced I<from>.
1259
1260=item B<via { ... }>
a15dff8d 1261
6ba6d68c 1262This is just sugar for the type coercion construction syntax.
a15dff8d 1263
e7fcb7b2 1264It takes a subroutine reference. This reference will be called with
1265the value to be coerced in C<$_>. It is expected to return a new value
1266of the proper type for the coercion.
1267
a15dff8d 1268=back
1269
e7fcb7b2 1270=head2 Creating and Finding Type Constraints
1271
1272These are additional functions for creating and finding type
1273constraints. Most of these functions are not available for
1274importing. The ones that are importable as specified.
004222dc 1275
1276=over 4
1277
e7fcb7b2 1278=item B<find_type_constraint($type_name)>
eb4c4e82 1279
e7fcb7b2 1280This function can be used to locate the L<Moose::Meta::TypeConstraint>
1281object for a named type.
eb4c4e82 1282
e7fcb7b2 1283This function is importable.
004222dc 1284
e7fcb7b2 1285=item B<register_type_constraint($type_object)>
004222dc 1286
e7fcb7b2 1287This function will register a L<Moose::Meta::TypeConstraint> with the
1288global type registry.
004222dc 1289
e7fcb7b2 1290This function is importable.
004222dc 1291
e7fcb7b2 1292=item B<normalize_type_constraint_name($type_constraint_name)>
004222dc 1293
e7fcb7b2 1294This method takes a type constraint name and returns the normalized
1295form. This removes any whitespace in the string.
004222dc 1296
e7fcb7b2 1297=item B<create_type_constraint_union($pipe_separated_types | @type_constraint_names)>
004222dc 1298
2dae61ad 1299=item B<create_named_type_constraint_union($name, $pipe_separated_types | @type_constraint_names)>
1300
e7fcb7b2 1301This can take a union type specification like C<'Int|ArrayRef[Int]'>,
1302or a list of names. It returns a new
1303L<Moose::Meta::TypeConstraint::Union> object.
004222dc 1304
e7fcb7b2 1305=item B<create_parameterized_type_constraint($type_name)>
620db045 1306
e7fcb7b2 1307Given a C<$type_name> in the form of C<'BaseType[ContainerType]'>,
1308this will create a new L<Moose::Meta::TypeConstraint::Parameterized>
1309object. The C<BaseType> must exist already exist as a parameterizable
1310type.
620db045 1311
e7fcb7b2 1312=item B<create_class_type_constraint($class, $options)>
dabed765 1313
e7fcb7b2 1314Given a class name this function will create a new
1315L<Moose::Meta::TypeConstraint::Class> object for that class name.
004222dc 1316
e7fcb7b2 1317The C<$options> is a hash reference that will be passed to the
1318L<Moose::Meta::TypeConstraint::Class> constructor (as a hash).
620db045 1319
e7fcb7b2 1320=item B<create_role_type_constraint($role, $options)>
620db045 1321
e7fcb7b2 1322Given a role name this function will create a new
1323L<Moose::Meta::TypeConstraint::Role> object for that role name.
620db045 1324
e7fcb7b2 1325The C<$options> is a hash reference that will be passed to the
1326L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
620db045 1327
8a6c8c47 1328=item B<create_enum_type_constraint($name, $values)>
1329
1330Given a enum name this function will create a new
1331L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
1332
0a6bff54 1333=item B<create_duck_type_constraint($name, $methods)>
1334
1335Given a duck type name this function will create a new
1336L<Moose::Meta::TypeConstraint::DuckType> object for that enum name.
1337
e7fcb7b2 1338=item B<find_or_parse_type_constraint($type_name)>
620db045 1339
ec4b72d2 1340Given a type name, this first attempts to find a matching constraint
e7fcb7b2 1341in the global registry.
620db045 1342
e7fcb7b2 1343If the type name is a union or parameterized type, it will create a
1344new object of the appropriate, but if given a "regular" type that does
1345not yet exist, it simply returns false.
620db045 1346
e7fcb7b2 1347When given a union or parameterized type, the member or base type must
1348already exist.
620db045 1349
e7fcb7b2 1350If it creates a new union or parameterized type, it will add it to the
1351global registry.
004222dc 1352
e7fcb7b2 1353=item B<find_or_create_isa_type_constraint($type_name)>
004222dc 1354
e7fcb7b2 1355=item B<find_or_create_does_type_constraint($type_name)>
004222dc 1356
e7fcb7b2 1357These functions will first call C<find_or_parse_type_constraint>. If
72042ad7 1358that function does not return a type, a new type object will
e7fcb7b2 1359be created.
004222dc 1360
e7fcb7b2 1361The C<isa> variant will use C<create_class_type_constraint> and the
1362C<does> variant will use C<create_role_type_constraint>.
004222dc 1363
1364=item B<get_type_constraint_registry>
1365
e7fcb7b2 1366Returns the L<Moose::Meta::TypeConstraint::Registry> object which
004222dc 1367keeps track of all type constraints.
1368
1369=item B<list_all_type_constraints>
1370
e7fcb7b2 1371This will return a list of type constraint names in the global
1372registry. You can then fetch the actual type object using
1373C<find_type_constraint($type_name)>.
004222dc 1374
1375=item B<list_all_builtin_type_constraints>
1376
e7fcb7b2 1377This will return a list of builtin type constraints, meaning those
1378which are defined in this module. See the L<Default Type Constraints>
1379section for a complete list.
004222dc 1380
1381=item B<export_type_constraints_as_functions>
1382
e7fcb7b2 1383This will export all the current type constraints as functions into
1384the caller's namespace (C<Int()>, C<Str()>, etc). Right now, this is
1385mostly used for testing, but it might prove useful to others.
004222dc 1386
1387=item B<get_all_parameterizable_types>
1388
e7fcb7b2 1389This returns all the parameterizable types that have been registered,
1390as a list of type objects.
004222dc 1391
e7fcb7b2 1392=item B<add_parameterizable_type($type)>
004222dc 1393
1394Adds C<$type> to the list of parameterizable types
1395
1396=back
1397
a15dff8d 1398=head1 BUGS
1399
d4048ef3 1400See L<Moose/BUGS> for details on reporting bugs.
a15dff8d 1401
81dc201f 1402=cut