| Filename | /home/hinrik/perl5/perlbrew/perls/perl-5.13.5/lib/site_perl/5.13.5/x86_64-linux/Mouse/Util/TypeConstraints.pm |
| Statements | Executed 763 statements in 5.51ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 46 | 2 | 1 | 763µs | 1.89ms | Mouse::Util::TypeConstraints::find_or_parse_type_constraint |
| 11 | 1 | 1 | 539µs | 1.38ms | Mouse::Util::TypeConstraints::_define_type |
| 42 | 2 | 2 | 383µs | 2.11ms | Mouse::Util::TypeConstraints::find_or_create_isa_type_constraint (recurses: max depth 1, inclusive time 31µs) |
| 13 | 2 | 2 | 199µs | 249µs | Mouse::Util::TypeConstraints::find_type_constraint |
| 81 | 6 | 1 | 152µs | 152µs | Mouse::Util::TypeConstraints::CORE:subst (opcode) |
| 9 | 1 | 1 | 150µs | 825µs | Mouse::Util::TypeConstraints::_parse_single_type (recurses: max depth 1, inclusive time 92µs) |
| 9 | 2 | 1 | 111µs | 895µs | Mouse::Util::TypeConstraints::_parse_type (recurses: max depth 1, inclusive time 135µs) |
| 9 | 1 | 1 | 110µs | 250µs | Mouse::Util::TypeConstraints::_parse_name |
| 9 | 1 | 1 | 94µs | 224µs | Mouse::Util::TypeConstraints::_parse_param (recurses: max depth 1, inclusive time 23µs) |
| 9 | 1 | 1 | 92µs | 108µs | Mouse::Util::TypeConstraints::_find_or_create_regular_type |
| 6 | 2 | 2 | 88µs | 977µs | Mouse::Util::TypeConstraints::class_type |
| 11 | 2 | 1 | 76µs | 1.45ms | Mouse::Util::TypeConstraints::subtype |
| 5 | 2 | 2 | 60µs | 656µs | Mouse::Util::TypeConstraints::role_type |
| 2 | 1 | 1 | 42µs | 269µs | Mouse::Util::TypeConstraints::_find_or_create_parameterized_type |
| 4 | 1 | 1 | 41µs | 896µs | Mouse::Util::TypeConstraints::find_or_create_does_type_constraint |
| 3 | 3 | 1 | 38µs | 347µs | Mouse::Util::TypeConstraints::__ANON__[:217] |
| 11 | 1 | 1 | 31µs | 31µs | Mouse::Util::TypeConstraints::CORE:match (opcode) |
| 1 | 1 | 1 | 25µs | 65µs | Mouse::Util::TypeConstraints::BEGIN@2 |
| 2 | 1 | 1 | 20µs | 23µs | Mouse::Util::TypeConstraints::_parameterize_HashRef_for (xsub) |
| 1 | 1 | 1 | 16µs | 24µs | Mouse::Util::TypeConstraints::BEGIN@5 |
| 1 | 1 | 1 | 7µs | 7µs | Mouse::Util::TypeConstraints::BEGIN@4 |
| 1 | 1 | 1 | 6µs | 6µs | Mouse::Util::TypeConstraints::BEGIN@7 |
| 1 | 1 | 1 | 6µs | 6µs | Mouse::Util::TypeConstraints::BEGIN@8 |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::__ANON__[:241] |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::__ANON__[:261] |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::_find_or_create_union_type |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::as |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::coerce |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::duck_type |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::enum |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::from |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::list_all_builtin_type_constraints |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::list_all_type_constraints |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::message |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::optimize_as |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::optimized_constraints |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::register_type_constraint |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::type |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::via |
| 0 | 0 | 0 | 0s | 0s | Mouse::Util::TypeConstraints::where |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Mouse::Util::TypeConstraints; | ||||
| 2 | 2 | 29µs | 2 | 106µs | # spent 65µs (25+41) within Mouse::Util::TypeConstraints::BEGIN@2 which was called:
# once (25µs+41µs) by Mouse::BEGIN@18 at line 2 # spent 65µs making 1 call to Mouse::Util::TypeConstraints::BEGIN@2
# spent 41µs making 1 call to Mouse::Exporter::do_import |
| 3 | |||||
| 4 | 2 | 24µs | 1 | 7µs | # spent 7µs within Mouse::Util::TypeConstraints::BEGIN@4 which was called:
# once (7µs+0s) by Mouse::BEGIN@18 at line 4 # spent 7µs making 1 call to Mouse::Util::TypeConstraints::BEGIN@4 |
| 5 | 2 | 25µs | 2 | 31µs | # spent 24µs (16+8) within Mouse::Util::TypeConstraints::BEGIN@5 which was called:
# once (16µs+8µs) by Mouse::BEGIN@18 at line 5 # spent 24µs making 1 call to Mouse::Util::TypeConstraints::BEGIN@5
# spent 8µs making 1 call to Mouse::Exporter::import |
| 6 | |||||
| 7 | 2 | 21µs | 1 | 6µs | # spent 6µs within Mouse::Util::TypeConstraints::BEGIN@7 which was called:
# once (6µs+0s) by Mouse::BEGIN@18 at line 7 # spent 6µs making 1 call to Mouse::Util::TypeConstraints::BEGIN@7 |
| 8 | 2 | 1.97ms | 1 | 6µs | # spent 6µs within Mouse::Util::TypeConstraints::BEGIN@8 which was called:
# once (6µs+0s) by Mouse::BEGIN@18 at line 8 # spent 6µs making 1 call to Mouse::Util::TypeConstraints::BEGIN@8 |
| 9 | |||||
| 10 | 1 | 8µs | 1 | 271µs | Mouse::Exporter->setup_import_methods( # spent 271µs making 1 call to Mouse::Exporter::setup_import_methods |
| 11 | as_is => [qw( | ||||
| 12 | as where message optimize_as | ||||
| 13 | from via | ||||
| 14 | |||||
| 15 | type subtype class_type role_type duck_type | ||||
| 16 | enum | ||||
| 17 | coerce | ||||
| 18 | |||||
| 19 | find_type_constraint | ||||
| 20 | register_type_constraint | ||||
| 21 | )], | ||||
| 22 | ); | ||||
| 23 | |||||
| 24 | 1 | 2µs | our @CARP_NOT = qw(Mouse::Meta::Attribute); | ||
| 25 | |||||
| 26 | 1 | 1µs | my %TYPE; | ||
| 27 | |||||
| 28 | # The root type | ||||
| 29 | 1 | 5µs | 1 | 65µs | $TYPE{Any} = Mouse::Meta::TypeConstraint->new( # spent 65µs making 1 call to Mouse::Meta::TypeConstraint::new |
| 30 | name => 'Any', | ||||
| 31 | ); | ||||
| 32 | |||||
| 33 | 1 | 15µs | my @builtins = ( | ||
| 34 | # $name => $parent, $code, | ||||
| 35 | |||||
| 36 | # the base type | ||||
| 37 | Item => 'Any', undef, | ||||
| 38 | |||||
| 39 | # the maybe[] type | ||||
| 40 | Maybe => 'Item', undef, | ||||
| 41 | |||||
| 42 | # value types | ||||
| 43 | Undef => 'Item', \&Undef, | ||||
| 44 | Defined => 'Item', \&Defined, | ||||
| 45 | Bool => 'Item', \&Bool, | ||||
| 46 | Value => 'Defined', \&Value, | ||||
| 47 | Str => 'Value', \&Str, | ||||
| 48 | Num => 'Str', \&Num, | ||||
| 49 | Int => 'Num', \&Int, | ||||
| 50 | |||||
| 51 | # ref types | ||||
| 52 | Ref => 'Defined', \&Ref, | ||||
| 53 | ScalarRef => 'Ref', \&ScalarRef, | ||||
| 54 | ArrayRef => 'Ref', \&ArrayRef, | ||||
| 55 | HashRef => 'Ref', \&HashRef, | ||||
| 56 | CodeRef => 'Ref', \&CodeRef, | ||||
| 57 | RegexpRef => 'Ref', \&RegexpRef, | ||||
| 58 | GlobRef => 'Ref', \&GlobRef, | ||||
| 59 | |||||
| 60 | # object types | ||||
| 61 | FileHandle => 'GlobRef', \&FileHandle, | ||||
| 62 | Object => 'Ref', \&Object, | ||||
| 63 | |||||
| 64 | # special string types | ||||
| 65 | ClassName => 'Str', \&ClassName, | ||||
| 66 | RoleName => 'ClassName', \&RoleName, | ||||
| 67 | ); | ||||
| 68 | |||||
| 69 | 1 | 116µs | 20 | 600µs | while (my ($name, $parent, $code) = splice @builtins, 0, 3) { # spent 600µs making 20 calls to Mouse::Meta::TypeConstraint::new, avg 30µs/call |
| 70 | $TYPE{$name} = Mouse::Meta::TypeConstraint->new( | ||||
| 71 | name => $name, | ||||
| 72 | parent => $TYPE{$parent}, | ||||
| 73 | optimized => $code, | ||||
| 74 | ); | ||||
| 75 | } | ||||
| 76 | |||||
| 77 | # parametarizable types | ||||
| 78 | 1 | 1µs | $TYPE{Maybe} {constraint_generator} = \&_parameterize_Maybe_for; | ||
| 79 | 1 | 2µs | $TYPE{ArrayRef}{constraint_generator} = \&_parameterize_ArrayRef_for; | ||
| 80 | 1 | 1µs | $TYPE{HashRef} {constraint_generator} = \&_parameterize_HashRef_for; | ||
| 81 | |||||
| 82 | # sugars | ||||
| 83 | sub as ($) { (as => $_[0]) } ## no critic | ||||
| 84 | sub where (&) { (where => $_[0]) } ## no critic | ||||
| 85 | sub message (&) { (message => $_[0]) } ## no critic | ||||
| 86 | sub optimize_as (&) { (optimize_as => $_[0]) } ## no critic | ||||
| 87 | |||||
| 88 | sub from { @_ } | ||||
| 89 | sub via (&) { $_[0] } ## no critic | ||||
| 90 | |||||
| 91 | # type utilities | ||||
| 92 | |||||
| 93 | sub optimized_constraints { # DEPRECATED | ||||
| 94 | Carp::cluck('optimized_constraints() has been deprecated'); | ||||
| 95 | return \%TYPE; | ||||
| 96 | } | ||||
| 97 | |||||
| 98 | 1 | 1µs | undef @builtins; # free the allocated memory | ||
| 99 | 1 | 5µs | @builtins = keys %TYPE; # reuse it | ||
| 100 | sub list_all_builtin_type_constraints { @builtins } | ||||
| 101 | sub list_all_type_constraints { keys %TYPE } | ||||
| 102 | |||||
| 103 | # spent 1.38ms (539µs+837µs) within Mouse::Util::TypeConstraints::_define_type which was called 11 times, avg 125µs/call:
# 11 times (539µs+837µs) by Mouse::Util::TypeConstraints::subtype at line 183, avg 125µs/call | ||||
| 104 | 154 | 404µs | my $is_subtype = shift; | ||
| 105 | my $name; | ||||
| 106 | my %args; | ||||
| 107 | |||||
| 108 | if(@_ == 1 && ref $_[0] ){ # @_ : { name => $name, where => ... } | ||||
| 109 | %args = %{$_[0]}; | ||||
| 110 | } | ||||
| 111 | elsif(@_ == 2 && ref $_[1]) { # @_ : $name => { where => ... } | ||||
| 112 | $name = $_[0]; | ||||
| 113 | %args = %{$_[1]}; | ||||
| 114 | } | ||||
| 115 | elsif(@_ % 2) { # @_ : $name => ( where => ... ) | ||||
| 116 | ($name, %args) = @_; | ||||
| 117 | } | ||||
| 118 | else{ # @_ : (name => $name, where => ...) | ||||
| 119 | %args = @_; | ||||
| 120 | } | ||||
| 121 | |||||
| 122 | if(!defined $name){ | ||||
| 123 | $name = $args{name}; | ||||
| 124 | } | ||||
| 125 | |||||
| 126 | $args{name} = $name; | ||||
| 127 | |||||
| 128 | my $parent = delete $args{as}; | ||||
| 129 | if($is_subtype && !$parent){ | ||||
| 130 | $parent = delete $args{name}; | ||||
| 131 | $name = undef; | ||||
| 132 | } | ||||
| 133 | |||||
| 134 | 11 | 329µs | if(defined $parent) { # spent 360µs making 11 calls to Mouse::Util::TypeConstraints::find_or_create_isa_type_constraint, avg 33µs/call, recursion: max depth 1, sum of overlapping time 31µs | ||
| 135 | $args{parent} = find_or_create_isa_type_constraint($parent); | ||||
| 136 | } | ||||
| 137 | |||||
| 138 | 33 | 56µs | if(defined $name){ | ||
| 139 | # set 'package_defined_in' only if it is not a core package | ||||
| 140 | my $this = $args{package_defined_in}; | ||||
| 141 | 22 | 95µs | if(!$this){ | ||
| 142 | $this = caller(1); | ||||
| 143 | 11 | 31µs | if($this !~ /\A Mouse \b/xms){ # spent 31µs making 11 calls to Mouse::Util::TypeConstraints::CORE:match, avg 3µs/call | ||
| 144 | $args{package_defined_in} = $this; | ||||
| 145 | } | ||||
| 146 | } | ||||
| 147 | |||||
| 148 | if(defined $TYPE{$name}){ | ||||
| 149 | my $that = $TYPE{$name}->{package_defined_in} || __PACKAGE__; | ||||
| 150 | if($this ne $that) { | ||||
| 151 | my $note = ''; | ||||
| 152 | if($that eq __PACKAGE__) { | ||||
| 153 | $note = sprintf " ('%s' is %s type constraint)", | ||||
| 154 | $name, | ||||
| 155 | scalar(grep { $name eq $_ } list_all_builtin_type_constraints()) | ||||
| 156 | ? 'a builtin' | ||||
| 157 | : 'an implicitly created'; | ||||
| 158 | } | ||||
| 159 | Carp::croak("The type constraint '$name' has already been created in $that" | ||||
| 160 | . " and cannot be created again in $this" . $note); | ||||
| 161 | } | ||||
| 162 | } | ||||
| 163 | } | ||||
| 164 | |||||
| 165 | $args{constraint} = delete $args{where} if exists $args{where}; | ||||
| 166 | $args{optimized} = delete $args{optimized_as} if exists $args{optimized_as}; | ||||
| 167 | |||||
| 168 | 11 | 445µs | my $constraint = Mouse::Meta::TypeConstraint->new(%args); # spent 445µs making 11 calls to Mouse::Meta::TypeConstraint::new, avg 40µs/call | ||
| 169 | |||||
| 170 | if(defined $name){ | ||||
| 171 | return $TYPE{$name} = $constraint; | ||||
| 172 | } | ||||
| 173 | else{ | ||||
| 174 | return $constraint; | ||||
| 175 | } | ||||
| 176 | } | ||||
| 177 | |||||
| 178 | sub type { | ||||
| 179 | return _define_type 0, @_; | ||||
| 180 | } | ||||
| 181 | |||||
| 182 | # spent 1.45ms (76µs+1.38) within Mouse::Util::TypeConstraints::subtype which was called 11 times, avg 132µs/call:
# 6 times (44µs+812µs) by Mouse::Util::TypeConstraints::class_type at line 200, avg 143µs/call
# 5 times (31µs+564µs) by Mouse::Util::TypeConstraints::role_type at line 218, avg 119µs/call | ||||
| 183 | 11 | 73µs | 11 | 1.38ms | return _define_type 1, @_; # spent 1.38ms making 11 calls to Mouse::Util::TypeConstraints::_define_type, avg 125µs/call |
| 184 | } | ||||
| 185 | |||||
| 186 | sub coerce { # coerce $type, from $from, via { ... }, ... | ||||
| 187 | my $type_name = shift; | ||||
| 188 | my $type = find_type_constraint($type_name) | ||||
| 189 | or Carp::croak("Cannot find type '$type_name', perhaps you forgot to load it."); | ||||
| 190 | |||||
| 191 | $type->_add_type_coercions(@_); | ||||
| 192 | return; | ||||
| 193 | } | ||||
| 194 | |||||
| 195 | # spent 977µs (88+888) within Mouse::Util::TypeConstraints::class_type which was called 6 times, avg 163µs/call:
# 5 times (74µs+743µs) by Mouse::init_meta at line 143 of Mouse.pm, avg 163µs/call
# once (14µs+146µs) by Mouse::Util::TypeConstraints::find_or_create_isa_type_constraint at line 418 | ||||
| 196 | 18 | 123µs | my($name, $options) = @_; | ||
| 197 | my $class = $options->{class} || $name; | ||||
| 198 | |||||
| 199 | # ClassType | ||||
| 200 | 12 | 889µs | return subtype $name => ( # spent 856µs making 6 calls to Mouse::Util::TypeConstraints::subtype, avg 143µs/call
# spent 32µs making 6 calls to Mouse::Util::generate_isa_predicate_for, avg 5µs/call | ||
| 201 | as => 'Object', | ||||
| 202 | optimized_as => Mouse::Util::generate_isa_predicate_for($class), | ||||
| 203 | class => $class, | ||||
| 204 | ); | ||||
| 205 | } | ||||
| 206 | |||||
| 207 | # spent 656µs (60+595) within Mouse::Util::TypeConstraints::role_type which was called 5 times, avg 131µs/call:
# 4 times (46µs+464µs) by Mouse::Util::TypeConstraints::find_or_create_does_type_constraint at line 413, avg 127µs/call
# once (14µs+132µs) by Mouse::Role::init_meta at line 124 of Mouse/Role.pm | ||||
| 208 | 15 | 60µs | my($name, $options) = @_; | ||
| 209 | my $role = $options->{role} || $name; | ||||
| 210 | |||||
| 211 | # RoleType | ||||
| 212 | return subtype $name => ( | ||||
| 213 | as => 'Object', | ||||
| 214 | # spent 347µs (38+309) within Mouse::Util::TypeConstraints::__ANON__[/home/hinrik/perl5/perlbrew/perls/perl-5.13.5/lib/site_perl/5.13.5/x86_64-linux/Mouse/Util/TypeConstraints.pm:217] which was called 3 times, avg 116µs/call:
# once (13µs+103µs) by Hailo::_storage at line 309 of Hailo.pm
# once (13µs+103µs) by Hailo::_tokenizer at line 317 of Hailo.pm
# once (12µs+103µs) by Hailo::_engine at line 316 of Hailo.pm | ||||
| 215 | 3 | 45µs | 6 | 309µs | return Scalar::Util::blessed($_[0]) # spent 303µs making 3 calls to Mouse::Util::does_role, avg 101µs/call
# spent 6µs making 3 calls to Scalar::Util::blessed, avg 2µs/call |
| 216 | && Mouse::Util::does_role($_[0], $role); | ||||
| 217 | }, | ||||
| 218 | 5 | 595µs | role => $role, # spent 595µs making 5 calls to Mouse::Util::TypeConstraints::subtype, avg 119µs/call | ||
| 219 | ); | ||||
| 220 | } | ||||
| 221 | |||||
| 222 | sub duck_type { | ||||
| 223 | my($name, @methods); | ||||
| 224 | |||||
| 225 | if(ref($_[0]) ne 'ARRAY'){ | ||||
| 226 | $name = shift; | ||||
| 227 | } | ||||
| 228 | |||||
| 229 | @methods = (@_ == 1 && ref($_[0]) eq 'ARRAY') ? @{$_[0]} : @_; | ||||
| 230 | |||||
| 231 | # DuckType | ||||
| 232 | return _define_type 1, $name => ( | ||||
| 233 | as => 'Object', | ||||
| 234 | optimized_as => Mouse::Util::generate_can_predicate_for(\@methods), | ||||
| 235 | message => sub { | ||||
| 236 | my($object) = @_; | ||||
| 237 | my @missing = grep { !$object->can($_) } @methods; | ||||
| 238 | return ref($object) | ||||
| 239 | . ' is missing methods ' | ||||
| 240 | . Mouse::Util::quoted_english_list(@missing); | ||||
| 241 | }, | ||||
| 242 | methods => \@methods, | ||||
| 243 | ); | ||||
| 244 | } | ||||
| 245 | |||||
| 246 | sub enum { | ||||
| 247 | my($name, %valid); | ||||
| 248 | |||||
| 249 | if(!(@_ == 1 && ref($_[0]) eq 'ARRAY')){ | ||||
| 250 | $name = shift; | ||||
| 251 | } | ||||
| 252 | |||||
| 253 | %valid = map{ $_ => undef } | ||||
| 254 | (@_ == 1 && ref($_[0]) eq 'ARRAY' ? @{$_[0]} : @_); | ||||
| 255 | |||||
| 256 | # EnumType | ||||
| 257 | return _define_type 1, $name => ( | ||||
| 258 | as => 'Str', | ||||
| 259 | optimized_as => sub{ | ||||
| 260 | return defined($_[0]) && !ref($_[0]) && exists $valid{$_[0]}; | ||||
| 261 | }, | ||||
| 262 | ); | ||||
| 263 | } | ||||
| 264 | |||||
| 265 | # spent 108µs (92+16) within Mouse::Util::TypeConstraints::_find_or_create_regular_type which was called 9 times, avg 12µs/call:
# 9 times (92µs+16µs) by Mouse::Util::TypeConstraints::_parse_name at line 328, avg 12µs/call | ||||
| 266 | 28 | 92µs | my($spec, $create) = @_; | ||
| 267 | |||||
| 268 | return $TYPE{$spec} if exists $TYPE{$spec}; | ||||
| 269 | |||||
| 270 | 5 | 16µs | my $meta = Mouse::Util::get_metaclass_by_name($spec); # spent 16µs making 5 calls to Mouse::Meta::Module::_get_metaclass_by_name, avg 3µs/call | ||
| 271 | |||||
| 272 | if(!defined $meta){ | ||||
| 273 | return $create ? class_type($spec) : undef; | ||||
| 274 | } | ||||
| 275 | |||||
| 276 | if(Mouse::Util::is_a_metarole($meta)){ | ||||
| 277 | return role_type($spec); | ||||
| 278 | } | ||||
| 279 | else{ | ||||
| 280 | return class_type($spec); | ||||
| 281 | } | ||||
| 282 | } | ||||
| 283 | |||||
| 284 | # spent 269µs (42+227) within Mouse::Util::TypeConstraints::_find_or_create_parameterized_type which was called 2 times, avg 134µs/call:
# 2 times (42µs+227µs) by Mouse::Util::TypeConstraints::_parse_single_type at line 340, avg 134µs/call | ||||
| 285 | 6 | 48µs | my($base, $param) = @_; | ||
| 286 | |||||
| 287 | 4 | 7µs | my $name = sprintf '%s[%s]', $base->name, $param->name; # spent 7µs making 4 calls to Mouse::Meta::TypeConstraint::name, avg 2µs/call | ||
| 288 | |||||
| 289 | 2 | 220µs | $TYPE{$name} ||= $base->parameterize($param, $name); # spent 220µs making 2 calls to Mouse::Meta::TypeConstraint::parameterize, avg 110µs/call | ||
| 290 | } | ||||
| 291 | |||||
| 292 | sub _find_or_create_union_type{ | ||||
| 293 | return if grep{ not defined } @_; | ||||
| 294 | my @types = sort map{ $_->{type_constraints} ? @{$_->{type_constraints}} : $_ } @_; | ||||
| 295 | |||||
| 296 | my $name = join '|', @types; | ||||
| 297 | |||||
| 298 | # UnionType | ||||
| 299 | $TYPE{$name} ||= Mouse::Meta::TypeConstraint->new( | ||||
| 300 | name => $name, | ||||
| 301 | type_constraints => \@types, | ||||
| 302 | ); | ||||
| 303 | } | ||||
| 304 | |||||
| 305 | # The type parser | ||||
| 306 | |||||
| 307 | # param : '[' type ']' | NOTHING | ||||
| 308 | # spent 224µs (94+130) within Mouse::Util::TypeConstraints::_parse_param which was called 9 times, avg 25µs/call:
# 9 times (94µs+130µs) by Mouse::Util::TypeConstraints::_parse_single_type at line 338, avg 25µs/call | ||||
| 309 | 25 | 86µs | my($c) = @_; | ||
| 310 | |||||
| 311 | 4 | 26µs | 9 | 14µs | if($c->{spec} =~ s/^\[//){ # spent 14µs making 9 calls to Mouse::Util::TypeConstraints::CORE:subst, avg 2µs/call |
| 312 | 2 | 0s | my $type = _parse_type($c, 1); # spent 135µs making 2 calls to Mouse::Util::TypeConstraints::_parse_type, avg 68µs/call, recursion: max depth 1, sum of overlapping time 135µs | ||
| 313 | |||||
| 314 | 2 | 4µs | if($c->{spec} =~ s/^\]//){ # spent 4µs making 2 calls to Mouse::Util::TypeConstraints::CORE:subst, avg 2µs/call | ||
| 315 | return $type; | ||||
| 316 | } | ||||
| 317 | Carp::croak("Syntax error in type: missing right square bracket in '$c->{orig}'"); | ||||
| 318 | } | ||||
| 319 | |||||
| 320 | return undef; | ||||
| 321 | } | ||||
| 322 | |||||
| 323 | # name : [\w.:]+ | ||||
| 324 | # spent 250µs (110+140) within Mouse::Util::TypeConstraints::_parse_name which was called 9 times, avg 28µs/call:
# 9 times (110µs+140µs) by Mouse::Util::TypeConstraints::_parse_single_type at line 337, avg 28µs/call | ||||
| 325 | 18 | 80µs | my($c, $create) = @_; | ||
| 326 | |||||
| 327 | 9 | 63µs | 9 | 32µs | if($c->{spec} =~ s/\A ([\w.:]+) //xms){ # spent 32µs making 9 calls to Mouse::Util::TypeConstraints::CORE:subst, avg 4µs/call |
| 328 | 9 | 108µs | return _find_or_create_regular_type($1, $create); # spent 108µs making 9 calls to Mouse::Util::TypeConstraints::_find_or_create_regular_type, avg 12µs/call | ||
| 329 | } | ||||
| 330 | Carp::croak("Syntax error in type: expect type name near '$c->{spec}' in '$c->{orig}'"); | ||||
| 331 | } | ||||
| 332 | |||||
| 333 | # single_type : name param | ||||
| 334 | # spent 825µs (150+674) within Mouse::Util::TypeConstraints::_parse_single_type which was called 9 times, avg 92µs/call:
# 9 times (150µs+674µs) by Mouse::Util::TypeConstraints::_parse_type at line 360, avg 92µs/call | ||||
| 335 | 36 | 110µs | my($c, $create) = @_; | ||
| 336 | |||||
| 337 | 9 | 250µs | my $type = _parse_name($c, $create); # spent 250µs making 9 calls to Mouse::Util::TypeConstraints::_parse_name, avg 28µs/call | ||
| 338 | 9 | 224µs | my $param = _parse_param($c); # spent 247µs making 9 calls to Mouse::Util::TypeConstraints::_parse_param, avg 27µs/call, recursion: max depth 1, sum of overlapping time 23µs | ||
| 339 | |||||
| 340 | 7 | 26µs | 2 | 269µs | if(defined $type){ # spent 269µs making 2 calls to Mouse::Util::TypeConstraints::_find_or_create_parameterized_type, avg 134µs/call |
| 341 | if(defined $param){ | ||||
| 342 | return _find_or_create_parameterized_type($type, $param); | ||||
| 343 | } | ||||
| 344 | else { | ||||
| 345 | return $type; | ||||
| 346 | } | ||||
| 347 | } | ||||
| 348 | elsif(defined $param){ | ||||
| 349 | Carp::croak("Undefined type with parameter [$param] in '$c->{orig}'"); | ||||
| 350 | } | ||||
| 351 | else{ | ||||
| 352 | return undef; | ||||
| 353 | } | ||||
| 354 | } | ||||
| 355 | |||||
| 356 | # type : single_type ('|' single_type)* | ||||
| 357 | # spent 895µs (111+784) within Mouse::Util::TypeConstraints::_parse_type which was called 9 times, avg 99µs/call:
# 7 times (71µs+825µs) by Mouse::Util::TypeConstraints::find_or_parse_type_constraint at line 402, avg 128µs/call
# 2 times (41µs+-41µs) by Mouse::Util::TypeConstraints::_parse_param at line 312, avg 0s/call | ||||
| 358 | 36 | 104µs | my($c, $create) = @_; | ||
| 359 | |||||
| 360 | 9 | 825µs | my $type = _parse_single_type($c, $create); # spent 916µs making 9 calls to Mouse::Util::TypeConstraints::_parse_single_type, avg 102µs/call, recursion: max depth 1, sum of overlapping time 92µs | ||
| 361 | 6 | 19µs | if($c->{spec}){ # can be an union type | ||
| 362 | my @types; | ||||
| 363 | 2 | 2µs | while($c->{spec} =~ s/^\|//){ # spent 2µs making 2 calls to Mouse::Util::TypeConstraints::CORE:subst, avg 1µs/call | ||
| 364 | push @types, _parse_single_type($c, $create); | ||||
| 365 | } | ||||
| 366 | if(@types){ | ||||
| 367 | return _find_or_create_union_type($type, @types); | ||||
| 368 | } | ||||
| 369 | } | ||||
| 370 | return $type; | ||||
| 371 | } | ||||
| 372 | |||||
| 373 | |||||
| 374 | # spent 249µs (199+50) within Mouse::Util::TypeConstraints::find_type_constraint which was called 13 times, avg 19µs/call:
# 9 times (142µs+34µs) by Mouse::init_meta at line 143 of Mouse.pm, avg 20µs/call
# 4 times (58µs+16µs) by Mouse::Role::init_meta at line 124 of Mouse/Role.pm, avg 18µs/call | ||||
| 375 | 52 | 249µs | my($spec) = @_; | ||
| 376 | 13 | 23µs | return $spec if Mouse::Util::is_a_type_constraint($spec) or not defined $spec; # spent 23µs making 13 calls to Mouse::Util::is_a_type_constraint, avg 2µs/call | ||
| 377 | |||||
| 378 | 13 | 27µs | $spec =~ s/\s+//g; # spent 27µs making 13 calls to Mouse::Util::TypeConstraints::CORE:subst, avg 2µs/call | ||
| 379 | return $TYPE{$spec}; | ||||
| 380 | } | ||||
| 381 | |||||
| 382 | sub register_type_constraint { | ||||
| 383 | my($constraint) = @_; | ||||
| 384 | Carp::croak("No type supplied / type is not a valid type constraint") | ||||
| 385 | unless Mouse::Util::is_a_type_constraint($constraint); | ||||
| 386 | my $name = $constraint->name; | ||||
| 387 | Carp::croak("Can't register an unnamed type constraint") | ||||
| 388 | unless defined $name; | ||||
| 389 | return $TYPE{$name} = $constraint; | ||||
| 390 | } | ||||
| 391 | |||||
| 392 | # spent 1.89ms (763µs+1.12) within Mouse::Util::TypeConstraints::find_or_parse_type_constraint which was called 46 times, avg 41µs/call:
# 42 times (677µs+864µs) by Mouse::Util::TypeConstraints::find_or_create_isa_type_constraint at line 418, avg 37µs/call
# 4 times (87µs+259µs) by Mouse::Util::TypeConstraints::find_or_create_does_type_constraint at line 413, avg 86µs/call | ||||
| 393 | 184 | 965µs | my($spec) = @_; | ||
| 394 | 46 | 85µs | return $spec if Mouse::Util::is_a_type_constraint($spec) or not defined $spec; # spent 85µs making 46 calls to Mouse::Util::is_a_type_constraint, avg 2µs/call | ||
| 395 | |||||
| 396 | 46 | 74µs | $spec =~ s/\s+//g; # spent 74µs making 46 calls to Mouse::Util::TypeConstraints::CORE:subst, avg 2µs/call | ||
| 397 | 28 | 68µs | 39 | 70µs | return $TYPE{$spec} || do{ # spent 70µs making 39 calls to Mouse::Meta::TypeConstraint::_identity, avg 2µs/call |
| 398 | my $context = { | ||||
| 399 | spec => $spec, | ||||
| 400 | orig => $spec, | ||||
| 401 | }; | ||||
| 402 | 7 | 895µs | my $type = _parse_type($context); # spent 895µs making 7 calls to Mouse::Util::TypeConstraints::_parse_type, avg 128µs/call | ||
| 403 | |||||
| 404 | if($context->{spec}){ | ||||
| 405 | Carp::croak("Syntax error: extra elements '$context->{spec}' in '$context->{orig}'"); | ||||
| 406 | } | ||||
| 407 | $type; | ||||
| 408 | }; | ||||
| 409 | } | ||||
| 410 | |||||
| 411 | # spent 896µs (41+856) within Mouse::Util::TypeConstraints::find_or_create_does_type_constraint which was called 4 times, avg 224µs/call:
# 4 times (41µs+856µs) by Mouse::Meta::Attribute::_process_options at line 56 of Mouse/Meta/Attribute.pm, avg 224µs/call | ||||
| 412 | # XXX: Moose does not register a new role_type, but Mouse does. | ||||
| 413 | 4 | 38µs | 8 | 856µs | return find_or_parse_type_constraint(@_) || role_type(@_); # spent 510µs making 4 calls to Mouse::Util::TypeConstraints::role_type, avg 127µs/call
# spent 346µs making 4 calls to Mouse::Util::TypeConstraints::find_or_parse_type_constraint, avg 86µs/call |
| 414 | } | ||||
| 415 | |||||
| 416 | # spent 2.11ms (383µs+1.73) within Mouse::Util::TypeConstraints::find_or_create_isa_type_constraint which was called 42 times, avg 50µs/call:
# 31 times (279µs+1.50ms) by Mouse::Meta::Attribute::_process_options at line 56 of Mouse/Meta/Attribute.pm, avg 57µs/call
# 11 times (104µs+225µs) by Mouse::Util::TypeConstraints::_define_type at line 134, avg 30µs/call | ||||
| 417 | # XXX: Moose does not register a new class_type, but Mouse does. | ||||
| 418 | 42 | 440µs | 84 | 1.76ms | return find_or_parse_type_constraint(@_) || class_type(@_); # spent 1.54ms making 42 calls to Mouse::Util::TypeConstraints::find_or_parse_type_constraint, avg 37µs/call
# spent 160µs making 1 call to Mouse::Util::TypeConstraints::class_type
# spent 59µs making 41 calls to Mouse::Meta::TypeConstraint::_identity, avg 1µs/call |
| 419 | } | ||||
| 420 | |||||
| 421 | 1 | 22µs | 1; | ||
| 422 | __END__ | ||||
# spent 31µs within Mouse::Util::TypeConstraints::CORE:match which was called 11 times, avg 3µs/call:
# 11 times (31µs+0s) by Mouse::Util::TypeConstraints::_define_type at line 143, avg 3µs/call | |||||
# spent 152µs within Mouse::Util::TypeConstraints::CORE:subst which was called 81 times, avg 2µs/call:
# 46 times (74µs+0s) by Mouse::Util::TypeConstraints::find_or_parse_type_constraint at line 396, avg 2µs/call
# 13 times (27µs+0s) by Mouse::Util::TypeConstraints::find_type_constraint at line 378, avg 2µs/call
# 9 times (32µs+0s) by Mouse::Util::TypeConstraints::_parse_name at line 327, avg 4µs/call
# 9 times (14µs+0s) by Mouse::Util::TypeConstraints::_parse_param at line 311, avg 2µs/call
# 2 times (4µs+0s) by Mouse::Util::TypeConstraints::_parse_param at line 314, avg 2µs/call
# 2 times (2µs+0s) by Mouse::Util::TypeConstraints::_parse_type at line 363, avg 1µs/call | |||||
# spent 23µs (20+3) within Mouse::Util::TypeConstraints::_parameterize_HashRef_for which was called 2 times, avg 12µs/call:
# 2 times (20µs+3µs) by Mouse::Meta::TypeConstraint::new at line 32 of Mouse/Meta/TypeConstraint.pm, avg 12µs/call |