line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Moose::Meta::TypeConstraint; |
2
|
|
|
|
|
|
|
our $VERSION = '2.2203'; |
3
|
|
|
|
|
|
|
|
4
|
401
|
|
|
401
|
|
111890
|
use strict; |
|
401
|
|
|
|
|
848
|
|
|
401
|
|
|
|
|
11863
|
|
5
|
401
|
|
|
401
|
|
1899
|
use warnings; |
|
401
|
|
|
|
|
774
|
|
|
401
|
|
|
|
|
9150
|
|
6
|
401
|
|
|
401
|
|
136838
|
use metaclass; |
|
401
|
|
|
|
|
992
|
|
|
401
|
|
|
|
|
2071
|
|
7
|
|
|
|
|
|
|
|
8
|
3529
|
|
|
3529
|
|
13587
|
use overload '0+' => sub { refaddr(shift) }, # id an object |
9
|
169
|
|
|
169
|
|
30532
|
'""' => sub { shift->name }, # stringify to tc name |
10
|
91988
|
|
|
91988
|
|
265031
|
bool => sub { 1 }, |
11
|
401
|
|
|
401
|
|
2988
|
fallback => 1; |
|
401
|
|
|
|
|
886
|
|
|
401
|
|
|
|
|
5761
|
|
12
|
|
|
|
|
|
|
|
13
|
401
|
|
|
401
|
|
44657
|
use Eval::Closure; |
|
401
|
|
|
|
|
837
|
|
|
401
|
|
|
|
|
22892
|
|
14
|
401
|
|
|
401
|
|
2641
|
use Scalar::Util qw(refaddr); |
|
401
|
|
|
|
|
1011
|
|
|
401
|
|
|
|
|
18156
|
|
15
|
401
|
|
|
401
|
|
2815
|
use Sub::Util qw(set_subname); |
|
401
|
|
|
|
|
945
|
|
|
401
|
|
|
|
|
18032
|
|
16
|
401
|
|
|
401
|
|
2561
|
use Try::Tiny; |
|
401
|
|
|
|
|
905
|
|
|
401
|
|
|
|
|
21154
|
|
17
|
|
|
|
|
|
|
|
18
|
401
|
|
|
401
|
|
2541
|
use parent 'Class::MOP::Object'; |
|
401
|
|
|
|
|
890
|
|
|
401
|
|
|
|
|
2567
|
|
19
|
|
|
|
|
|
|
|
20
|
401
|
|
|
401
|
|
27647
|
use Moose::Util 'throw_exception'; |
|
401
|
|
|
|
|
905
|
|
|
401
|
|
|
|
|
2748
|
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
__PACKAGE__->meta->add_attribute('name' => ( |
23
|
|
|
|
|
|
|
reader => 'name', |
24
|
|
|
|
|
|
|
Class::MOP::_definition_context(), |
25
|
|
|
|
|
|
|
)); |
26
|
|
|
|
|
|
|
__PACKAGE__->meta->add_attribute('parent' => ( |
27
|
|
|
|
|
|
|
reader => 'parent', |
28
|
|
|
|
|
|
|
predicate => 'has_parent', |
29
|
|
|
|
|
|
|
Class::MOP::_definition_context(), |
30
|
|
|
|
|
|
|
)); |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
my $null_constraint = sub { 1 }; |
33
|
|
|
|
|
|
|
__PACKAGE__->meta->add_attribute('constraint' => ( |
34
|
|
|
|
|
|
|
reader => 'constraint', |
35
|
|
|
|
|
|
|
writer => '_set_constraint', |
36
|
|
|
|
|
|
|
default => sub { $null_constraint }, |
37
|
|
|
|
|
|
|
Class::MOP::_definition_context(), |
38
|
|
|
|
|
|
|
)); |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
__PACKAGE__->meta->add_attribute('message' => ( |
41
|
|
|
|
|
|
|
accessor => 'message', |
42
|
|
|
|
|
|
|
predicate => 'has_message', |
43
|
|
|
|
|
|
|
Class::MOP::_definition_context(), |
44
|
|
|
|
|
|
|
)); |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
__PACKAGE__->meta->add_attribute('_default_message' => ( |
47
|
|
|
|
|
|
|
accessor => '_default_message', |
48
|
|
|
|
|
|
|
Class::MOP::_definition_context(), |
49
|
|
|
|
|
|
|
)); |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# can't make this a default because it has to close over the type name, and |
52
|
|
|
|
|
|
|
# cmop attributes don't have lazy |
53
|
|
|
|
|
|
|
my $_default_message_generator = sub { |
54
|
|
|
|
|
|
|
my $name = shift; |
55
|
|
|
|
|
|
|
sub { |
56
|
|
|
|
|
|
|
my $value = shift; |
57
|
|
|
|
|
|
|
# have to load it late like this, since it uses Moose itself |
58
|
|
|
|
|
|
|
my $can_partialdump = try { |
59
|
|
|
|
|
|
|
# versions prior to 0.14 had a potential infinite loop bug |
60
|
|
|
|
|
|
|
require Devel::PartialDump; |
61
|
|
|
|
|
|
|
Devel::PartialDump->VERSION(0.14); |
62
|
|
|
|
|
|
|
1; |
63
|
|
|
|
|
|
|
}; |
64
|
|
|
|
|
|
|
if ($can_partialdump) { |
65
|
|
|
|
|
|
|
$value = Devel::PartialDump->new->dump($value); |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
else { |
68
|
|
|
|
|
|
|
$value = (defined $value ? overload::StrVal($value) : 'undef'); |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
return "Validation failed for '" . $name . "' with value $value"; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
}; |
73
|
|
|
|
|
|
|
__PACKAGE__->meta->add_attribute('coercion' => ( |
74
|
|
|
|
|
|
|
accessor => 'coercion', |
75
|
|
|
|
|
|
|
predicate => 'has_coercion', |
76
|
|
|
|
|
|
|
Class::MOP::_definition_context(), |
77
|
|
|
|
|
|
|
)); |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
__PACKAGE__->meta->add_attribute('inlined' => ( |
80
|
|
|
|
|
|
|
init_arg => 'inlined', |
81
|
|
|
|
|
|
|
accessor => 'inlined', |
82
|
|
|
|
|
|
|
predicate => '_has_inlined_type_constraint', |
83
|
|
|
|
|
|
|
Class::MOP::_definition_context(), |
84
|
|
|
|
|
|
|
)); |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
__PACKAGE__->meta->add_attribute('inline_environment' => ( |
87
|
|
|
|
|
|
|
init_arg => 'inline_environment', |
88
|
|
|
|
|
|
|
accessor => '_inline_environment', |
89
|
|
|
|
|
|
|
default => sub { {} }, |
90
|
|
|
|
|
|
|
Class::MOP::_definition_context(), |
91
|
|
|
|
|
|
|
)); |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub parents { |
94
|
1
|
|
|
1
|
1
|
4
|
my $self = shift; |
95
|
1
|
|
|
|
|
5
|
$self->parent; |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# private accessors |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
__PACKAGE__->meta->add_attribute('compiled_type_constraint' => ( |
101
|
|
|
|
|
|
|
accessor => '_compiled_type_constraint', |
102
|
|
|
|
|
|
|
predicate => '_has_compiled_type_constraint', |
103
|
|
|
|
|
|
|
Class::MOP::_definition_context(), |
104
|
|
|
|
|
|
|
)); |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
__PACKAGE__->meta->add_attribute('package_defined_in' => ( |
107
|
|
|
|
|
|
|
accessor => '_package_defined_in', |
108
|
|
|
|
|
|
|
Class::MOP::_definition_context(), |
109
|
|
|
|
|
|
|
)); |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub new { |
112
|
11906
|
|
|
11906
|
1
|
23748
|
my $class = shift; |
113
|
11906
|
|
|
|
|
30038
|
my ($first, @rest) = @_; |
114
|
11906
|
100
|
|
|
|
53679
|
my %args = ref $first ? %$first : $first ? ($first, @rest) : (); |
|
|
100
|
|
|
|
|
|
115
|
11906
|
100
|
|
|
|
41714
|
$args{name} = $args{name} ? "$args{name}" : "__ANON__"; |
116
|
|
|
|
|
|
|
|
117
|
11906
|
100
|
66
|
|
|
26751
|
if ( exists $args{message} |
|
|
|
66
|
|
|
|
|
118
|
|
|
|
|
|
|
&& (!ref($args{message}) || ref($args{message}) ne 'CODE') ) { |
119
|
1
|
|
|
|
|
6
|
throw_exception( MessageParameterMustBeCodeRef => params => \%args, |
120
|
|
|
|
|
|
|
class => $class |
121
|
|
|
|
|
|
|
); |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
11905
|
|
|
|
|
336696
|
my $self = $class->_new(%args); |
125
|
11905
|
50
|
|
|
|
401333
|
$self->compile_type_constraint() |
126
|
|
|
|
|
|
|
unless $self->_has_compiled_type_constraint; |
127
|
11899
|
100
|
|
|
|
335205
|
$self->_default_message($_default_message_generator->($self->name)) |
128
|
|
|
|
|
|
|
unless $self->has_message; |
129
|
11899
|
|
|
|
|
59675
|
return $self; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub coerce { |
135
|
133
|
|
|
133
|
1
|
922
|
my $self = shift; |
136
|
|
|
|
|
|
|
|
137
|
133
|
|
|
|
|
3088
|
my $coercion = $self->coercion; |
138
|
|
|
|
|
|
|
|
139
|
133
|
100
|
|
|
|
355
|
unless ($coercion) { |
140
|
2
|
|
|
|
|
46
|
throw_exception( CoercingWithoutCoercions => type_name => $self->name ); |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
|
143
|
131
|
100
|
|
|
|
339
|
return $_[0] if $self->check($_[0]); |
144
|
|
|
|
|
|
|
|
145
|
116
|
|
|
|
|
1064
|
return $coercion->coerce(@_); |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
sub assert_coerce { |
149
|
3
|
|
|
3
|
1
|
2562
|
my $self = shift; |
150
|
|
|
|
|
|
|
|
151
|
3
|
|
|
|
|
8
|
my $result = $self->coerce(@_); |
152
|
|
|
|
|
|
|
|
153
|
3
|
|
|
|
|
15
|
$self->assert_valid($result); |
154
|
|
|
|
|
|
|
|
155
|
2
|
|
|
|
|
22
|
return $result; |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
sub check { |
159
|
9440
|
|
|
9440
|
1
|
150209
|
my ($self, @args) = @_; |
160
|
9440
|
|
|
|
|
289388
|
my $constraint_subref = $self->_compiled_type_constraint; |
161
|
9440
|
100
|
|
|
|
110822
|
return $constraint_subref->(@args) ? 1 : undef; |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
sub validate { |
165
|
18
|
|
|
18
|
1
|
509
|
my ($self, $value) = @_; |
166
|
18
|
100
|
|
|
|
671
|
if ($self->_compiled_type_constraint->($value)) { |
167
|
6
|
|
|
|
|
47
|
return undef; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
else { |
170
|
12
|
|
|
|
|
84
|
$self->get_message($value); |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub can_be_inlined { |
175
|
48500
|
|
|
48500
|
1
|
63075
|
my $self = shift; |
176
|
|
|
|
|
|
|
|
177
|
48500
|
100
|
100
|
|
|
1265154
|
if ( $self->has_parent && $self->constraint == $null_constraint ) { |
178
|
1107
|
|
|
|
|
27683
|
return $self->parent->can_be_inlined; |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
|
181
|
47393
|
|
|
|
|
1363219
|
return $self->_has_inlined_type_constraint; |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub _inline_check { |
185
|
24886
|
|
|
24886
|
|
35545
|
my $self = shift; |
186
|
|
|
|
|
|
|
|
187
|
24886
|
100
|
|
|
|
39239
|
unless ( $self->can_be_inlined ) { |
188
|
2
|
|
|
|
|
47
|
throw_exception( CannotInlineTypeConstraintCheck => type_name => $self->name ); |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
24884
|
100
|
100
|
|
|
638213
|
if ( $self->has_parent && $self->constraint == $null_constraint ) { |
192
|
522
|
|
|
|
|
13543
|
return $self->parent->_inline_check(@_); |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
24362
|
|
|
|
|
572513
|
return '( do { ' . $self->inlined->( $self, @_ ) . ' } )'; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
sub inline_environment { |
199
|
21879
|
|
|
21879
|
1
|
36187
|
my $self = shift; |
200
|
|
|
|
|
|
|
|
201
|
21879
|
100
|
100
|
|
|
575579
|
if ( $self->has_parent && $self->constraint == $null_constraint ) { |
202
|
506
|
|
|
|
|
12935
|
return $self->parent->inline_environment; |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
21373
|
|
|
|
|
625582
|
return $self->_inline_environment; |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
sub assert_valid { |
209
|
8
|
|
|
8
|
1
|
756
|
my ( $self, $value ) = @_; |
210
|
|
|
|
|
|
|
|
211
|
8
|
100
|
|
|
|
25
|
return 1 if $self->check($value); |
212
|
|
|
|
|
|
|
|
213
|
3
|
|
|
|
|
39
|
throw_exception( |
214
|
|
|
|
|
|
|
'ValidationFailedForTypeConstraint', |
215
|
|
|
|
|
|
|
type => $self, |
216
|
|
|
|
|
|
|
value => $value |
217
|
|
|
|
|
|
|
); |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
sub get_message { |
221
|
926
|
|
|
926
|
1
|
1866
|
my ($self, $value) = @_; |
222
|
926
|
100
|
|
|
|
23456
|
my $msg = $self->has_message |
223
|
|
|
|
|
|
|
? $self->message |
224
|
|
|
|
|
|
|
: $self->_default_message; |
225
|
926
|
|
|
|
|
1625
|
local $_ = $value; |
226
|
926
|
|
|
|
|
2037
|
return $msg->($value); |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
## type predicates ... |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
sub equals { |
232
|
1765
|
|
|
1765
|
1
|
3368
|
my ( $self, $type_or_name ) = @_; |
233
|
|
|
|
|
|
|
|
234
|
1765
|
|
|
|
|
3304
|
my $other = Moose::Util::TypeConstraints::find_type_constraint($type_or_name); |
235
|
1765
|
100
|
|
|
|
3057
|
return if not $other; |
236
|
|
|
|
|
|
|
|
237
|
1764
|
100
|
|
|
|
3546
|
return 1 if $self == $other; |
238
|
|
|
|
|
|
|
|
239
|
1357
|
100
|
|
|
|
33052
|
return unless $self->constraint == $other->constraint; |
240
|
|
|
|
|
|
|
|
241
|
1
|
50
|
|
|
|
26
|
if ( $self->has_parent ) { |
242
|
0
|
0
|
|
|
|
0
|
return unless $other->has_parent; |
243
|
0
|
0
|
|
|
|
0
|
return unless $self->parent->equals( $other->parent ); |
244
|
|
|
|
|
|
|
} else { |
245
|
1
|
50
|
|
|
|
26
|
return if $other->has_parent; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
1
|
|
|
|
|
6
|
return; |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub is_a_type_of { |
252
|
265
|
|
|
265
|
1
|
949
|
my ($self, $type_or_name) = @_; |
253
|
|
|
|
|
|
|
|
254
|
265
|
|
|
|
|
793
|
my $type = Moose::Util::TypeConstraints::find_type_constraint($type_or_name); |
255
|
265
|
100
|
|
|
|
771
|
return if not $type; |
256
|
|
|
|
|
|
|
|
257
|
261
|
100
|
|
|
|
1070
|
($self->equals($type) || $self->is_subtype_of($type)); |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
sub is_subtype_of { |
261
|
579
|
|
|
579
|
1
|
2043
|
my ($self, $type_or_name) = @_; |
262
|
|
|
|
|
|
|
|
263
|
579
|
|
|
|
|
1537
|
my $type = Moose::Util::TypeConstraints::find_type_constraint($type_or_name); |
264
|
579
|
100
|
|
|
|
1484
|
return if not $type; |
265
|
|
|
|
|
|
|
|
266
|
575
|
|
|
|
|
1002
|
my $current = $self; |
267
|
|
|
|
|
|
|
|
268
|
575
|
|
|
|
|
13786
|
while (my $parent = $current->parent) { |
269
|
1602
|
100
|
|
|
|
2926
|
return 1 if $parent->equals($type); |
270
|
1285
|
|
|
|
|
29289
|
$current = $parent; |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
|
273
|
258
|
|
|
|
|
1078
|
return 0; |
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
## compiling the type constraint |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
sub compile_type_constraint { |
279
|
14981
|
|
|
14981
|
0
|
22413
|
my $self = shift; |
280
|
14981
|
|
|
|
|
31363
|
$self->_compiled_type_constraint($self->_actually_compile_type_constraint); |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
## type compilers ... |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
sub _actually_compile_type_constraint { |
286
|
14908
|
|
|
14908
|
|
20348
|
my $self = shift; |
287
|
|
|
|
|
|
|
|
288
|
14908
|
100
|
|
|
|
30793
|
if ( $self->can_be_inlined ) { |
289
|
14791
|
|
|
|
|
35012
|
return eval_closure( |
290
|
|
|
|
|
|
|
source => 'sub { ' . $self->_inline_check('$_[0]') . ' }', |
291
|
|
|
|
|
|
|
environment => $self->inline_environment, |
292
|
|
|
|
|
|
|
); |
293
|
|
|
|
|
|
|
} |
294
|
|
|
|
|
|
|
|
295
|
117
|
|
|
|
|
2896
|
my $check = $self->constraint; |
296
|
117
|
100
|
|
|
|
406
|
unless ( defined $check ) { |
297
|
1
|
|
|
|
|
23
|
throw_exception( NoConstraintCheckForTypeConstraint => type_name => $self->name ); |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
|
300
|
116
|
100
|
|
|
|
3148
|
return $self->_compile_subtype($check) |
301
|
|
|
|
|
|
|
if $self->has_parent; |
302
|
|
|
|
|
|
|
|
303
|
20
|
|
|
|
|
86
|
return $self->_compile_type($check); |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
sub _compile_subtype { |
307
|
125
|
|
|
125
|
|
349
|
my ($self, $check) = @_; |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
# gather all the parent constraints in order |
310
|
125
|
|
|
|
|
263
|
my @parents; |
311
|
125
|
|
|
|
|
434
|
foreach my $parent ($self->_collect_all_parents) { |
312
|
627
|
|
|
|
|
14329
|
push @parents => $parent->constraint; |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
|
315
|
125
|
|
|
|
|
372
|
@parents = grep { $_ != $null_constraint } reverse @parents; |
|
627
|
|
|
|
|
1262
|
|
316
|
|
|
|
|
|
|
|
317
|
125
|
100
|
|
|
|
388
|
unless ( @parents ) { |
318
|
2
|
|
|
|
|
6
|
return $self->_compile_type($check); |
319
|
|
|
|
|
|
|
} else { |
320
|
|
|
|
|
|
|
# general case, check all the constraints, from the first parent to ourselves |
321
|
123
|
|
|
|
|
322
|
my @checks = @parents; |
322
|
123
|
100
|
|
|
|
468
|
push @checks, $check if $check != $null_constraint; |
323
|
|
|
|
|
|
|
return set_subname( |
324
|
|
|
|
|
|
|
$self->name => sub { |
325
|
1772
|
|
|
1772
|
|
235085
|
my (@args) = @_; |
326
|
1772
|
|
|
|
|
2886
|
local $_ = $args[0]; |
327
|
1772
|
|
|
|
|
3371
|
foreach my $check (@checks) { |
328
|
8098
|
100
|
|
|
|
16754
|
return undef unless $check->(@args); |
329
|
|
|
|
|
|
|
} |
330
|
1029
|
|
|
|
|
5942
|
return 1; |
331
|
|
|
|
|
|
|
} |
332
|
123
|
|
|
|
|
3162
|
); |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
} |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
sub _compile_type { |
337
|
48
|
|
|
48
|
|
125
|
my ($self, $check) = @_; |
338
|
|
|
|
|
|
|
|
339
|
48
|
100
|
|
|
|
437
|
return $check if $check == $null_constraint; # Item, Any |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
return set_subname( |
342
|
|
|
|
|
|
|
$self->name => sub { |
343
|
756
|
|
|
756
|
|
9633
|
my (@args) = @_; |
344
|
756
|
|
|
|
|
1412
|
local $_ = $args[0]; |
345
|
756
|
|
|
|
|
2024
|
$check->(@args); |
346
|
|
|
|
|
|
|
} |
347
|
39
|
|
|
|
|
997
|
); |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
## other utils ... |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
sub _collect_all_parents { |
353
|
138
|
|
|
138
|
|
280
|
my $self = shift; |
354
|
138
|
|
|
|
|
228
|
my @parents; |
355
|
138
|
|
|
|
|
3710
|
my $current = $self->parent; |
356
|
138
|
|
|
|
|
429
|
while (defined $current) { |
357
|
683
|
|
|
|
|
1152
|
push @parents => $current; |
358
|
683
|
|
|
|
|
15218
|
$current = $current->parent; |
359
|
|
|
|
|
|
|
} |
360
|
138
|
|
|
|
|
521
|
return @parents; |
361
|
|
|
|
|
|
|
} |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
sub create_child_type { |
364
|
6489
|
|
|
6489
|
1
|
19687
|
my ($self, %opts) = @_; |
365
|
6489
|
|
|
|
|
11619
|
my $class = ref $self; |
366
|
6489
|
|
|
|
|
19266
|
return $class->new(%opts, parent => $self); |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
1; |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
# ABSTRACT: The Moose Type Constraint metaclass |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
__END__ |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
=pod |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
=encoding UTF-8 |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=head1 NAME |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
Moose::Meta::TypeConstraint - The Moose Type Constraint metaclass |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=head1 VERSION |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
version 2.2203 |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=head1 DESCRIPTION |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
This class represents a single type constraint. Moose's built-in type |
390
|
|
|
|
|
|
|
constraints, as well as constraints you define, are all stored in a |
391
|
|
|
|
|
|
|
L<Moose::Meta::TypeConstraint::Registry> object as objects of this |
392
|
|
|
|
|
|
|
class. |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=head1 INHERITANCE |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
C<Moose::Meta::TypeConstraint> is a subclass of L<Class::MOP::Object>. |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
=head1 METHODS |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
=head2 Moose::Meta::TypeConstraint->new(%options) |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
This creates a new type constraint based on the provided C<%options>: |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
=over 4 |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
=item * name |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
The constraint name. If a name is not provided, it will be set to |
409
|
|
|
|
|
|
|
"__ANON__". |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
=item * parent |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
A C<Moose::Meta::TypeConstraint> object which is the parent type for |
414
|
|
|
|
|
|
|
the type being created. This is optional. |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
=item * constraint |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
This is the subroutine reference that implements the actual constraint |
419
|
|
|
|
|
|
|
check. This defaults to a subroutine which always returns true. |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
=item * message |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
A subroutine reference which is used to generate an error message when |
424
|
|
|
|
|
|
|
the constraint fails. This is optional. |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=item * coercion |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
A L<Moose::Meta::TypeCoercion> object representing the coercions to |
429
|
|
|
|
|
|
|
the type. This is optional. |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
=item * inlined |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
A subroutine which returns a string suitable for inlining this type |
434
|
|
|
|
|
|
|
constraint. It will be called as a method on the type constraint object, and |
435
|
|
|
|
|
|
|
will receive a single additional parameter, a variable name to be tested |
436
|
|
|
|
|
|
|
(usually C<"$_"> or C<"$_[0]">. |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
This is optional. |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
=item * inline_environment |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
A hash reference of variables to close over. The keys are variables names, and |
443
|
|
|
|
|
|
|
the values are I<references> to the variables. |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
=back |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
=head2 $constraint->equals($type_name_or_object) |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
Returns true if the supplied name or type object is the same as the |
450
|
|
|
|
|
|
|
current type. |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
=head2 $constraint->is_subtype_of($type_name_or_object) |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
Returns true if the supplied name or type object is a parent of the |
455
|
|
|
|
|
|
|
current type. |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
=head2 $constraint->is_a_type_of($type_name_or_object) |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
Returns true if the given type is the same as the current type, or is |
460
|
|
|
|
|
|
|
a parent of the current type. This is a shortcut for checking |
461
|
|
|
|
|
|
|
C<equals> and C<is_subtype_of>. |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
=head2 $constraint->coerce($value) |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
This will attempt to coerce the value to the type. If the type does not |
466
|
|
|
|
|
|
|
have any defined coercions this will throw an error. |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
If no coercion can produce a value matching C<$constraint>, the original |
469
|
|
|
|
|
|
|
value is returned. |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
=head2 $constraint->assert_coerce($value) |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
This method behaves just like C<coerce>, but if the result is not valid |
474
|
|
|
|
|
|
|
according to C<$constraint>, an error is thrown. |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
=head2 $constraint->check($value) |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
Returns true if the given value passes the constraint for the type. |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
=head2 $constraint->validate($value) |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
This is similar to C<check>. However, if the type I<is valid> then the |
483
|
|
|
|
|
|
|
method returns an explicit C<undef>. If the type is not valid, we call |
484
|
|
|
|
|
|
|
C<< $self->get_message($value) >> internally to generate an error |
485
|
|
|
|
|
|
|
message. |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=head2 $constraint->assert_valid($value) |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
Like C<check> and C<validate>, this method checks whether C<$value> is |
490
|
|
|
|
|
|
|
valid under the constraint. If it is, it will return true. If it is not, |
491
|
|
|
|
|
|
|
an exception will be thrown with the results of |
492
|
|
|
|
|
|
|
C<< $self->get_message($value) >>. |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
=head2 $constraint->name |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
Returns the type's name, as provided to the constructor. |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
=head2 $constraint->parent |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
Returns the type's parent, as provided to the constructor, if any. |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
=head2 $constraint->has_parent |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
Returns true if the type has a parent type. |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=head2 $constraint->parents |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
Returns all of the types parents as an list of type constraint objects. |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
=head2 $constraint->constraint |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
Returns the type's constraint, as provided to the constructor. |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
=head2 $constraint->get_message($value) |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
This generates a method for the given value. If the type does not have |
517
|
|
|
|
|
|
|
an explicit message, we generate a default message. |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=head2 $constraint->has_message |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
Returns true if the type has a message. |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
=head2 $constraint->message |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
Returns the type's message as a subroutine reference. |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
=head2 $constraint->coercion |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
Returns the type's L<Moose::Meta::TypeCoercion> object, if one |
530
|
|
|
|
|
|
|
exists. |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
=head2 $constraint->has_coercion |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
Returns true if the type has a coercion. |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
=head2 $constraint->can_be_inlined |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
Returns true if this type constraint can be inlined. A type constraint which |
539
|
|
|
|
|
|
|
subtypes an inlinable constraint and does not add an additional constraint |
540
|
|
|
|
|
|
|
"inherits" its parent type's inlining. |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
=head2 $constraint->create_child_type(%options) |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
This returns a new type constraint of the same class using the |
545
|
|
|
|
|
|
|
provided C<%options>. The C<parent> option will be the current type. |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
This method exists so that subclasses of this class can override this |
548
|
|
|
|
|
|
|
behavior and change how child types are created. |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
=head1 BUGS |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
See L<Moose/BUGS> for details on reporting bugs. |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
=head1 AUTHORS |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
=over 4 |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
=item * |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
Stevan Little <stevan@cpan.org> |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
=item * |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
Dave Rolsky <autarch@urth.org> |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
=item * |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
Jesse Luehrs <doy@cpan.org> |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
=item * |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
Shawn M Moore <sartak@cpan.org> |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
=item * |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org> |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
=item * |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
Karen Etheridge <ether@cpan.org> |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
=item * |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
Florian Ragwitz <rafl@debian.org> |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
=item * |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
Hans Dieter Pearcey <hdp@cpan.org> |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
=item * |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
Chris Prather <chris@prather.org> |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
=item * |
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
Matt S Trout <mstrout@cpan.org> |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
=back |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
This software is copyright (c) 2006 by Infinity Interactive, Inc. |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
605
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
=cut |