Filename | /home/hinrik/perl5/perlbrew/perls/perl-5.13.5/lib/site_perl/5.13.5/x86_64-linux/Mouse/Meta/TypeConstraint.pm |
Statements | Executed 680 statements in 3.01ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
34 | 4 | 2 | 1.24ms | 1.30ms | new | Mouse::Meta::TypeConstraint::
14 | 2 | 1 | 456µs | 601µs | is_a_type_of | Mouse::Meta::TypeConstraint::
89 | 5 | 4 | 146µs | 146µs | _identity (xsub) | Mouse::Meta::TypeConstraint::
54 | 3 | 2 | 79µs | 79µs | name (xsub) | Mouse::Meta::TypeConstraint::
36 | 14 | 6 | 58µs | 58µs | _compiled_type_constraint (xsub) | Mouse::Meta::TypeConstraint::
42 | 2 | 1 | 53µs | 53µs | parent (xsub) | Mouse::Meta::TypeConstraint::
5 | 1 | 1 | 35µs | 35µs | compile_type_constraint (xsub) | Mouse::Meta::TypeConstraint::
2 | 1 | 1 | 26µs | 220µs | parameterize | Mouse::Meta::TypeConstraint::
1 | 1 | 1 | 25µs | 111µs | BEGIN@2 | Mouse::Meta::TypeConstraint::
14 | 1 | 1 | 20µs | 20µs | CORE:subst (opcode) | Mouse::Meta::TypeConstraint::
0 | 0 | 0 | 0s | 0s | __ANON__[:119] | Mouse::Meta::TypeConstraint::
0 | 0 | 0 | 0s | 0s | __ANON__[:140] | Mouse::Meta::TypeConstraint::
0 | 0 | 0 | 0s | 0s | _add_type_coercions | Mouse::Meta::TypeConstraint::
0 | 0 | 0 | 0s | 0s | _as_string | Mouse::Meta::TypeConstraint::
0 | 0 | 0 | 0s | 0s | _compile_type_coercion | Mouse::Meta::TypeConstraint::
0 | 0 | 0 | 0s | 0s | _compile_union_type_coercion | Mouse::Meta::TypeConstraint::
0 | 0 | 0 | 0s | 0s | _unite | Mouse::Meta::TypeConstraint::
0 | 0 | 0 | 0s | 0s | assert_valid | Mouse::Meta::TypeConstraint::
0 | 0 | 0 | 0s | 0s | coerce | Mouse::Meta::TypeConstraint::
0 | 0 | 0 | 0s | 0s | create_child_type | Mouse::Meta::TypeConstraint::
0 | 0 | 0 | 0s | 0s | get_message | Mouse::Meta::TypeConstraint::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Mouse::Meta::TypeConstraint; | ||||
2 | 2 | 1.03ms | 2 | 196µs | # spent 111µs (25+86) within Mouse::Meta::TypeConstraint::BEGIN@2 which was called:
# once (25µs+86µs) by Mouse::Meta::Attribute::BEGIN@6 at line 2 # spent 111µs making 1 call to Mouse::Meta::TypeConstraint::BEGIN@2
# spent 86µs making 1 call to Mouse::Exporter::do_import |
3 | |||||
4 | # spent 1.30ms (1.24+61µs) within Mouse::Meta::TypeConstraint::new which was called 34 times, avg 38µs/call:
# 20 times (592µs+8µs) by Mouse::BEGIN@18 at line 69 of Mouse/Util/TypeConstraints.pm, avg 30µs/call
# 11 times (445µs+0s) by Mouse::Util::TypeConstraints::_define_type at line 168 of Mouse/Util/TypeConstraints.pm, avg 40µs/call
# 2 times (149µs+44µs) by Mouse::Meta::TypeConstraint::parameterize at line 204, avg 97µs/call
# once (56µs+9µs) by Mouse::BEGIN@18 at line 29 of Mouse/Util/TypeConstraints.pm | ||||
5 | 34 | 41µs | my $class = shift; | ||
6 | 34 | 124µs | my %args = @_ == 1 ? %{$_[0]} : @_; | ||
7 | |||||
8 | 34 | 43µs | $args{name} = '__ANON__' if !defined $args{name}; | ||
9 | |||||
10 | 34 | 73µs | if(defined $args{parent}) { | ||
11 | 33 | 214µs | %args = (%{$args{parent}}, %args); | ||
12 | # a child type must not inherit 'compiled_type_constraint' | ||||
13 | # and 'hand_optimized_type_constraint' from the parent | ||||
14 | 33 | 46µs | delete $args{compiled_type_constraint}; | ||
15 | 33 | 40µs | delete $args{hand_optimized_type_constraint}; | ||
16 | 33 | 54µs | if(defined(my $parent_tp = $args{parent}{type_parameter})) { | ||
17 | delete $args{type_parameter} if $parent_tp == $args{type_parameter}; | ||||
18 | } | ||||
19 | } | ||||
20 | |||||
21 | 34 | 31µs | my $check; | ||
22 | |||||
23 | 34 | 91µs | 2 | 3µs | if($check = delete $args{optimized}) { # spent 3µs making 2 calls to Mouse::Meta::TypeConstraint::_identity, avg 2µs/call |
24 | 29 | 34µs | $args{hand_optimized_type_constraint} = $check; | ||
25 | 29 | 34µs | $args{compiled_type_constraint} = $check; | ||
26 | } | ||||
27 | elsif(my $param = $args{type_parameter}) { | ||||
28 | 2 | 3µs | my $generator = $args{constraint_generator} | ||
29 | || $class->throw_error("The $args{name} constraint cannot be used," | ||||
30 | . " because $param doesn't subtype from a parameterizable type"); | ||||
31 | # it must be 'constraint' | ||||
32 | 2 | 34µs | 4 | 26µs | $check = $args{constraint} = $generator->($param); # spent 23µs making 2 calls to Mouse::Util::TypeConstraints::_parameterize_HashRef_for, avg 12µs/call
# spent 3µs making 2 calls to Mouse::Meta::TypeConstraint::_compiled_type_constraint, avg 2µs/call |
33 | } | ||||
34 | else { | ||||
35 | 3 | 4µs | $check = $args{constraint}; | ||
36 | } | ||||
37 | |||||
38 | 34 | 45µs | if(defined($check) && ref($check) ne 'CODE'){ | ||
39 | $class->throw_error( | ||||
40 | "Constraint for $args{name} is not a CODE reference"); | ||||
41 | } | ||||
42 | |||||
43 | 34 | 140µs | my $self = bless \%args, $class; | ||
44 | 34 | 96µs | 5 | 35µs | $self->compile_type_constraint() # spent 35µs making 5 calls to Mouse::Meta::TypeConstraint::compile_type_constraint, avg 7µs/call |
45 | if !$args{hand_optimized_type_constraint}; | ||||
46 | |||||
47 | 34 | 39µs | if($args{type_constraints}) { | ||
48 | $self->_compile_union_type_coercion(); | ||||
49 | } | ||||
50 | 34 | 152µs | return $self; | ||
51 | } | ||||
52 | |||||
53 | sub create_child_type { | ||||
54 | my $self = shift; | ||||
55 | return ref($self)->new(@_, parent => $self); | ||||
56 | } | ||||
57 | |||||
58 | sub name; | ||||
59 | sub parent; | ||||
60 | sub message; | ||||
61 | sub has_coercion; | ||||
62 | |||||
63 | sub check; | ||||
64 | |||||
65 | sub type_parameter; | ||||
66 | sub __is_parameterized; | ||||
67 | |||||
68 | sub _compiled_type_constraint; | ||||
69 | sub _compiled_type_coercion; | ||||
70 | |||||
71 | sub compile_type_constraint; | ||||
72 | |||||
73 | |||||
74 | sub _add_type_coercions { # ($self, @pairs) | ||||
75 | my $self = shift; | ||||
76 | |||||
77 | if(exists $self->{type_constraints}){ # union type | ||||
78 | $self->throw_error( | ||||
79 | "Cannot add additional type coercions to Union types '$self'"); | ||||
80 | } | ||||
81 | |||||
82 | my $coercions = ($self->{coercion_map} ||= []); | ||||
83 | my %has = map{ $_->[0] => undef } @{$coercions}; | ||||
84 | |||||
85 | for(my $i = 0; $i < @_; $i++){ | ||||
86 | my $from = $_[ $i]; | ||||
87 | my $action = $_[++$i]; | ||||
88 | |||||
89 | if(exists $has{$from}){ | ||||
90 | $self->throw_error("A coercion action already exists for '$from'"); | ||||
91 | } | ||||
92 | |||||
93 | my $type = Mouse::Util::TypeConstraints::find_or_parse_type_constraint($from) | ||||
94 | or $self->throw_error( | ||||
95 | "Could not find the type constraint ($from) to coerce from"); | ||||
96 | |||||
97 | push @{$coercions}, [ $type => $action ]; | ||||
98 | } | ||||
99 | |||||
100 | $self->_compile_type_coercion(); | ||||
101 | return; | ||||
102 | } | ||||
103 | |||||
104 | sub _compile_type_coercion { | ||||
105 | my($self) = @_; | ||||
106 | |||||
107 | my @coercions = @{$self->{coercion_map}}; | ||||
108 | |||||
109 | $self->{_compiled_type_coercion} = sub { | ||||
110 | my($thing) = @_; | ||||
111 | foreach my $pair (@coercions) { | ||||
112 | #my ($constraint, $converter) = @$pair; | ||||
113 | if ($pair->[0]->check($thing)) { | ||||
114 | local $_ = $thing; | ||||
115 | return $pair->[1]->($thing); | ||||
116 | } | ||||
117 | } | ||||
118 | return $thing; | ||||
119 | }; | ||||
120 | return; | ||||
121 | } | ||||
122 | |||||
123 | sub _compile_union_type_coercion { | ||||
124 | my($self) = @_; | ||||
125 | |||||
126 | my @coercions; | ||||
127 | foreach my $type(@{$self->{type_constraints}}){ | ||||
128 | if($type->has_coercion){ | ||||
129 | push @coercions, $type; | ||||
130 | } | ||||
131 | } | ||||
132 | if(@coercions){ | ||||
133 | $self->{_compiled_type_coercion} = sub { | ||||
134 | my($thing) = @_; | ||||
135 | foreach my $type(@coercions){ | ||||
136 | my $value = $type->coerce($thing); | ||||
137 | return $value if $self->check($value); | ||||
138 | } | ||||
139 | return $thing; | ||||
140 | }; | ||||
141 | } | ||||
142 | return; | ||||
143 | } | ||||
144 | |||||
145 | sub coerce { | ||||
146 | my $self = shift; | ||||
147 | return $_[0] if $self->check(@_); | ||||
148 | |||||
149 | my $coercion = $self->{_compiled_type_coercion} | ||||
150 | or $self->throw_error("Cannot coerce without a type coercion"); | ||||
151 | return $coercion->(@_); | ||||
152 | } | ||||
153 | |||||
154 | sub get_message { | ||||
155 | my ($self, $value) = @_; | ||||
156 | if ( my $msg = $self->message ) { | ||||
157 | local $_ = $value; | ||||
158 | return $msg->($value); | ||||
159 | } | ||||
160 | else { | ||||
161 | if(not defined $value) { | ||||
162 | $value = 'undef'; | ||||
163 | } | ||||
164 | elsif( ref($value) && defined(&overload::StrVal) ) { | ||||
165 | $value = overload::StrVal($value); | ||||
166 | } | ||||
167 | return "Validation failed for '$self' with value $value"; | ||||
168 | } | ||||
169 | } | ||||
170 | |||||
171 | # spent 601µs (456+145) within Mouse::Meta::TypeConstraint::is_a_type_of which was called 14 times, avg 43µs/call:
# 7 times (249µs+76µs) by Mouse::Meta::Attribute::_process_options at line 56 of Mouse/Meta/Attribute.pm, avg 47µs/call
# 7 times (207µs+68µs) by Mouse::Meta::Method::Accessor::XS::_generate_reader at line 257 of Mouse/Meta/Attribute.pm, avg 39µs/call | ||||
172 | 14 | 22µs | my($self, $other) = @_; | ||
173 | |||||
174 | # ->is_a_type_of('__ANON__') is always false | ||||
175 | 14 | 18µs | return 0 if !ref($other) && $other eq '__ANON__'; | ||
176 | |||||
177 | 14 | 75µs | 14 | 20µs | (my $other_name = $other) =~ s/\s+//g; # spent 20µs making 14 calls to Mouse::Meta::TypeConstraint::CORE:subst, avg 1µs/call |
178 | |||||
179 | 14 | 79µs | 14 | 22µs | return 1 if $self->name eq $other_name; # spent 22µs making 14 calls to Mouse::Meta::TypeConstraint::name, avg 2µs/call |
180 | |||||
181 | 12 | 16µs | if(exists $self->{type_constraints}){ # union | ||
182 | foreach my $type(@{$self->{type_constraints}}) { | ||||
183 | return 1 if $type->name eq $other_name; | ||||
184 | } | ||||
185 | } | ||||
186 | |||||
187 | 12 | 316µs | 66 | 87µs | for(my $p = $self->parent; defined $p; $p = $p->parent) { # spent 51µs making 36 calls to Mouse::Meta::TypeConstraint::name, avg 1µs/call
# spent 36µs making 30 calls to Mouse::Meta::TypeConstraint::parent, avg 1µs/call |
188 | return 1 if $p->name eq $other_name; | ||||
189 | 12 | 60µs | 12 | 16µs | } # spent 16µs making 12 calls to Mouse::Meta::TypeConstraint::parent, avg 1µs/call |
190 | |||||
191 | 6 | 24µs | return 0; | ||
192 | } | ||||
193 | |||||
194 | # See also Moose::Meta::TypeConstraint::Parameterizable | ||||
195 | # spent 220µs (26+194) within Mouse::Meta::TypeConstraint::parameterize which was called 2 times, avg 110µs/call:
# 2 times (26µs+194µs) by Mouse::Util::TypeConstraints::_find_or_create_parameterized_type at line 289 of Mouse/Util/TypeConstraints.pm, avg 110µs/call | ||||
196 | 2 | 4µs | my($self, $param, $name) = @_; | ||
197 | |||||
198 | 2 | 3µs | if(!ref $param){ | ||
199 | require Mouse::Util::TypeConstraints; | ||||
200 | $param = Mouse::Util::TypeConstraints::find_or_create_isa_type_constraint($param); | ||||
201 | } | ||||
202 | |||||
203 | 2 | 2µs | $name ||= sprintf '%s[%s]', $self->name, $param->name; | ||
204 | 2 | 18µs | 2 | 194µs | return Mouse::Meta::TypeConstraint->new( # spent 194µs making 2 calls to Mouse::Meta::TypeConstraint::new, avg 97µs/call |
205 | name => $name, | ||||
206 | parent => $self, | ||||
207 | type_parameter => $param, | ||||
208 | ); | ||||
209 | } | ||||
210 | |||||
211 | sub assert_valid { | ||||
212 | my ($self, $value) = @_; | ||||
213 | |||||
214 | if(!$self->check($value)){ | ||||
215 | $self->throw_error($self->get_message($value)); | ||||
216 | } | ||||
217 | return 1; | ||||
218 | } | ||||
219 | |||||
220 | sub _as_string { $_[0]->name } # overload "" | ||||
221 | sub _identity; # overload 0+ | ||||
222 | |||||
223 | sub _unite { # overload infix:<|> | ||||
224 | my($lhs, $rhs) = @_; | ||||
225 | require Mouse::Util::TypeConstraints; | ||||
226 | return Mouse::Util::TypeConstraints::find_or_parse_type_constraint( | ||||
227 | " $lhs | $rhs", | ||||
228 | ); | ||||
229 | } | ||||
230 | |||||
231 | 1 | 3µs | 1; | ||
232 | __END__ | ||||
# spent 20µs within Mouse::Meta::TypeConstraint::CORE:subst which was called 14 times, avg 1µs/call:
# 14 times (20µs+0s) by Mouse::Meta::TypeConstraint::is_a_type_of at line 177, avg 1µs/call | |||||
# spent 58µs within Mouse::Meta::TypeConstraint::_compiled_type_constraint which was called 36 times, avg 2µs/call:
# 13 times (20µs+0s) by Mouse::Object::new at line 9 of reply.pl, avg 2µs/call
# 10 times (15µs+0s) by Mouse::Object::new at line 207 of Hailo.pm, avg 1µs/call
# 2 times (3µs+0s) by Mouse::Util::TypeConstraints::_parameterize_HashRef_for at line 32, avg 2µs/call
# once (3µs+0s) by Hailo::Storage::sth at line 110 of Hailo/Storage.pm
# once (3µs+0s) by Hailo::Storage::dbh at line 115 of Hailo/Storage/SQLite.pm
# once (2µs+0s) by Hailo::Storage::_boundary_token_id at line 112 of Hailo/Storage.pm
# once (2µs+0s) by Hailo::_engine at line 316 of Hailo.pm
# once (2µs+0s) by Hailo::Engine::Default::repeat_limit at line 287 of Hailo/Engine/Default.pm
# once (2µs+0s) by Hailo::Storage::dbd at line 60 of Hailo/Storage.pm
# once (2µs+0s) by Hailo::Storage::dbi_options at line 45 of Hailo/Storage.pm
# once (2µs+0s) by Hailo::_storage at line 309 of Hailo.pm
# once (2µs+0s) by Hailo::brain at line 70 of Hailo.pm
# once (1µs+0s) by Hailo::Storage::dbd_options at line 61 of Hailo/Storage.pm
# once (1µs+0s) by Hailo::_tokenizer at line 317 of Hailo.pm | |||||
# spent 146µs within Mouse::Meta::TypeConstraint::_identity which was called 89 times, avg 2µs/call:
# 41 times (59µs+0s) by Mouse::Util::TypeConstraints::find_or_create_isa_type_constraint at line 418 of Mouse/Util/TypeConstraints.pm, avg 1µs/call
# 39 times (70µs+0s) by Mouse::Util::TypeConstraints::find_or_parse_type_constraint at line 397 of Mouse/Util/TypeConstraints.pm, avg 2µs/call
# 4 times (7µs+0s) by Mouse::init_meta at line 143 of Mouse.pm, avg 2µs/call
# 3 times (7µs+0s) by Mouse::Role::init_meta at line 124 of Mouse/Role.pm, avg 2µs/call
# 2 times (3µs+0s) by Mouse::Meta::TypeConstraint::new at line 23, avg 2µs/call | |||||
# spent 35µs within Mouse::Meta::TypeConstraint::compile_type_constraint which was called 5 times, avg 7µs/call:
# 5 times (35µs+0s) by Mouse::Meta::TypeConstraint::new at line 44, avg 7µs/call | |||||
# spent 79µs within Mouse::Meta::TypeConstraint::name which was called 54 times, avg 1µs/call:
# 36 times (51µs+0s) by Mouse::Meta::TypeConstraint::is_a_type_of at line 187, avg 1µs/call
# 14 times (22µs+0s) by Mouse::Meta::TypeConstraint::is_a_type_of at line 179, avg 2µs/call
# 4 times (7µs+0s) by Mouse::Util::TypeConstraints::_find_or_create_parameterized_type at line 287 of Mouse/Util/TypeConstraints.pm, avg 2µs/call | |||||
sub Mouse::Meta::TypeConstraint::parent; # xsub |