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