Profile of Moose/Util/TypeConstraints.pm

← Index
NYTProf Performance Profile «block view•line view•sub view»
For xt/tapper-mcp-scheduler-with-db-longrun.t
Run on Tue May 22 17:18:39 2012
Reported on Tue May 22 17:22:48 2012

Filename | /2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/Moose/Util/TypeConstraints.pm
Statements | Executed 1003 statements in 7.04ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 1.02ms | 3.39ms | Moose::Util::TypeConstraints::::BEGIN@33Moose::Util::TypeConstraints::BEGIN@33
1 | 1 | 1 | 803µs | 2.31ms | Moose::Util::TypeConstraints::::BEGIN@39Moose::Util::TypeConstraints::BEGIN@39
1 | 1 | 1 | 785µs | 1.09ms | Moose::Util::TypeConstraints::::BEGIN@614Moose::Util::TypeConstraints::BEGIN@614
1 | 1 | 1 | 764µs | 2.25ms | Moose::Util::TypeConstraints::::BEGIN@38Moose::Util::TypeConstraints::BEGIN@38
1 | 1 | 1 | 762µs | 2.06ms | Moose::Util::TypeConstraints::::BEGIN@36Moose::Util::TypeConstraints::BEGIN@36
1 | 1 | 1 | 733µs | 1.96ms | Moose::Util::TypeConstraints::::BEGIN@37Moose::Util::TypeConstraints::BEGIN@37
1 | 1 | 1 | 638µs | 4.76ms | Moose::Util::TypeConstraints::::BEGIN@34Moose::Util::TypeConstraints::BEGIN@34
1 | 1 | 1 | 506µs | 2.35ms | Moose::Util::TypeConstraints::::BEGIN@42Moose::Util::TypeConstraints::BEGIN@42
10 | 10 | 1 | 491µs | 491µs | Moose::Util::TypeConstraints::::CORE:regcompMoose::Util::TypeConstraints::CORE:regcomp (opcode)
50 | 10 | 6 | 477µs | 1.12ms | Moose::Util::TypeConstraints::::find_type_constraintMoose::Util::TypeConstraints::find_type_constraint
17 | 2 | 1 | 412µs | 6.12ms | Moose::Util::TypeConstraints::::_create_type_constraintMoose::Util::TypeConstraints::_create_type_constraint
8 | 2 | 1 | 263µs | 7.09ms | Moose::Util::TypeConstraints::::create_class_type_constraintMoose::Util::TypeConstraints::create_class_type_constraint
22 | 1 | 1 | 245µs | 1.07ms | Moose::Util::TypeConstraints::::find_or_parse_type_constraintMoose::Util::TypeConstraints::find_or_parse_type_constraint
16 | 1 | 1 | 164µs | 5.82ms | Moose::Util::TypeConstraints::::subtypeMoose::Util::TypeConstraints::subtype
22 | 2 | 2 | 161µs | 2.04ms | Moose::Util::TypeConstraints::::find_or_create_isa_type_constraintMoose::Util::TypeConstraints::find_or_create_isa_type_constraint
4 | 1 | 1 | 107µs | 2.37ms | Moose::Util::TypeConstraints::::create_role_type_constraintMoose::Util::TypeConstraints::create_role_type_constraint
22 | 1 | 1 | 91µs | 118µs | Moose::Util::TypeConstraints::::normalize_type_constraint_nameMoose::Util::TypeConstraints::normalize_type_constraint_name
7 | 1 | 1 | 40µs | 6.34ms | Moose::Util::TypeConstraints::::class_typeMoose::Util::TypeConstraints::class_type
19 | 3 | 1 | 36µs | 36µs | Moose::Util::TypeConstraints::::CORE:matchMoose::Util::TypeConstraints::CORE:match (opcode)
22 | 1 | 1 | 27µs | 27µs | Moose::Util::TypeConstraints::::CORE:substMoose::Util::TypeConstraints::CORE:subst (opcode)
16 | 1 | 1 | 27µs | 27µs | Moose::Util::TypeConstraints::::asMoose::Util::TypeConstraints::as
16 | 1 | 1 | 22µs | 22µs | Moose::Util::TypeConstraints::::whereMoose::Util::TypeConstraints::where
17 | 1 | 1 | 21µs | 21µs | Moose::Util::TypeConstraints::::inline_asMoose::Util::TypeConstraints::inline_as
10 | 10 | 1 | 21µs | 21µs | Moose::Util::TypeConstraints::::CORE:qrMoose::Util::TypeConstraints::CORE:qr (opcode)
4 | 1 | 1 | 18µs | 2.39ms | Moose::Util::TypeConstraints::::role_typeMoose::Util::TypeConstraints::role_type
1 | 1 | 1 | 18µs | 55µs | Moose::Util::TypeConstraints::::BEGIN@68Moose::Util::TypeConstraints::BEGIN@68
1 | 1 | 1 | 14µs | 472µs | Moose::Util::TypeConstraints::::typeMoose::Util::TypeConstraints::type
1 | 1 | 1 | 13µs | 142µs | Moose::Util::TypeConstraints::::_detect_type_constraint_unionMoose::Util::TypeConstraints::_detect_type_constraint_union
1 | 1 | 1 | 10µs | 26µs | Moose::Util::TypeConstraints::::BEGIN@667Moose::Util::TypeConstraints::BEGIN@667
1 | 1 | 1 | 9µs | 9µs | Moose::Util::TypeConstraints::::BEGIN@40Moose::Util::TypeConstraints::BEGIN@40
1 | 1 | 1 | 9µs | 57µs | Moose::Util::TypeConstraints::::_detect_parameterized_type_constraintMoose::Util::TypeConstraints::_detect_parameterized_type_constraint
1 | 1 | 1 | 8µs | 8µs | Moose::Util::TypeConstraints::::BEGIN@3Moose::Util::TypeConstraints::BEGIN@3
1 | 1 | 1 | 8µs | 16µs | Moose::Util::TypeConstraints::::BEGIN@31Moose::Util::TypeConstraints::BEGIN@31
1 | 1 | 1 | 8µs | 9µs | Moose::Util::TypeConstraints::::list_all_type_constraintsMoose::Util::TypeConstraints::list_all_type_constraints
1 | 1 | 1 | 8µs | 15µs | Moose::Util::TypeConstraints::::BEGIN@673Moose::Util::TypeConstraints::BEGIN@673
1 | 1 | 1 | 8µs | 35µs | Moose::Util::TypeConstraints::::BEGIN@11Moose::Util::TypeConstraints::BEGIN@11
1 | 1 | 1 | 8µs | 14µs | Moose::Util::TypeConstraints::::BEGIN@678Moose::Util::TypeConstraints::BEGIN@678
1 | 1 | 1 | 7µs | 14µs | Moose::Util::TypeConstraints::::BEGIN@694Moose::Util::TypeConstraints::BEGIN@694
1 | 1 | 1 | 7µs | 26µs | Moose::Util::TypeConstraints::::BEGIN@13Moose::Util::TypeConstraints::BEGIN@13
1 | 1 | 1 | 7µs | 30µs | Moose::Util::TypeConstraints::::BEGIN@12Moose::Util::TypeConstraints::BEGIN@12
1 | 1 | 1 | 6µs | 6µs | Moose::Util::TypeConstraints::::BEGIN@35Moose::Util::TypeConstraints::BEGIN@35
1 | 1 | 1 | 5µs | 5µs | Moose::Util::TypeConstraints::::BEGIN@41Moose::Util::TypeConstraints::BEGIN@41
1 | 1 | 1 | 5µs | 5µs | Moose::Util::TypeConstraints::::BEGIN@32Moose::Util::TypeConstraints::BEGIN@32
1 | 1 | 1 | 3µs | 3µs | Moose::Util::TypeConstraints::::BEGIN@10Moose::Util::TypeConstraints::BEGIN@10
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::__ANON__[:73]Moose::Util::TypeConstraints::__ANON__[:73]
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::_confessMoose::Util::TypeConstraints::_confess
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::_create_parameterized_type_constraintMoose::Util::TypeConstraints::_create_parameterized_type_constraint
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::_create_type_constraint_unionMoose::Util::TypeConstraints::_create_type_constraint_union
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::_install_type_coercionsMoose::Util::TypeConstraints::_install_type_coercions
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::_parse_parameterized_type_constraintMoose::Util::TypeConstraints::_parse_parameterized_type_constraint
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::_parse_type_constraint_unionMoose::Util::TypeConstraints::_parse_type_constraint_union
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::_throw_errorMoose::Util::TypeConstraints::_throw_error
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::add_parameterizable_typeMoose::Util::TypeConstraints::add_parameterizable_type
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::coerceMoose::Util::TypeConstraints::coerce
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::create_duck_type_constraintMoose::Util::TypeConstraints::create_duck_type_constraint
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::create_enum_type_constraintMoose::Util::TypeConstraints::create_enum_type_constraint
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::create_named_type_constraint_unionMoose::Util::TypeConstraints::create_named_type_constraint_union
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::create_parameterized_type_constraintMoose::Util::TypeConstraints::create_parameterized_type_constraint
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::create_type_constraint_unionMoose::Util::TypeConstraints::create_type_constraint_union
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::duck_typeMoose::Util::TypeConstraints::duck_type
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::enumMoose::Util::TypeConstraints::enum
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::export_type_constraints_as_functionsMoose::Util::TypeConstraints::export_type_constraints_as_functions
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::find_or_create_does_type_constraintMoose::Util::TypeConstraints::find_or_create_does_type_constraint
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::find_or_create_type_constraintMoose::Util::TypeConstraints::find_or_create_type_constraint
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::fromMoose::Util::TypeConstraints::from
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::get_all_parameterizable_typesMoose::Util::TypeConstraints::get_all_parameterizable_types
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::get_type_constraint_registryMoose::Util::TypeConstraints::get_type_constraint_registry
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::list_all_builtin_type_constraintsMoose::Util::TypeConstraints::list_all_builtin_type_constraints
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::match_on_typeMoose::Util::TypeConstraints::match_on_type
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::maybe_typeMoose::Util::TypeConstraints::maybe_type
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::messageMoose::Util::TypeConstraints::message
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::optimize_asMoose::Util::TypeConstraints::optimize_as
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::register_type_constraintMoose::Util::TypeConstraints::register_type_constraint
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::unionMoose::Util::TypeConstraints::union
0 | 0 | 0 | 0s | 0s | Moose::Util::TypeConstraints::::viaMoose::Util::TypeConstraints::via

Call graph for these subroutines as a Graphviz dot language file.

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