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