File Coverage

blib/lib/Moose/Util/TypeConstraints/Builtins.pm
Criterion Covered Total %
statement 117 122 95.9
branch 14 16 87.5
condition 14 17 82.3
subroutine 58 59 98.3
pod 0 6 0.0
total 203 220 92.2


line stmt bran cond sub pod time code
1             package Moose::Util::TypeConstraints::Builtins;
2             our $VERSION = '2.2205';
3              
4 390     390   3231 use strict;
  390         1069  
  390         15109  
5 390     390   2586 use warnings;
  390         927  
  390         16464  
6              
7 390     390   2461 use Class::Load qw( is_class_loaded );
  390         905  
  390         27770  
8 390     390   2902 use List::Util 1.33 ();
  390         11316  
  390         10266  
9 390     390   2504 use Scalar::Util qw( blessed );
  390         964  
  390         935943  
10              
11 390     390 0 1526 sub type { goto &Moose::Util::TypeConstraints::type }
12 6240     6240 0 15097 sub subtype { goto &Moose::Util::TypeConstraints::subtype }
13 6240     6240 0 15359 sub as { goto &Moose::Util::TypeConstraints::as }
14 6240     6240 0 23857 sub where (&) { goto &Moose::Util::TypeConstraints::where }
15 6630     6630 0 19020 sub inline_as (&) { goto &Moose::Util::TypeConstraints::inline_as }
16              
17             sub define_builtins {
18 390     390 0 1135 my $registry = shift;
19              
20             type 'Any' # meta-type including all
21 1778     1778   5694 => where {1}
22 390     923   2326 => inline_as { '1' };
  923         7468  
23              
24             subtype 'Item' # base type
25             => as 'Any'
26 390     0   3276 => inline_as { '1' };
  0         0  
27              
28             subtype 'Undef'
29             => as 'Item'
30 25     25   192 => where { !defined($_) }
31             => inline_as {
32 405     405   3121 '!defined(' . $_[1] . ')'
33 390         3560 };
34              
35             subtype 'Defined'
36             => as 'Item'
37 1623     1623   5208 => where { defined($_) }
38             => inline_as {
39 4060     4060   44348 'defined(' . $_[1] . ')'
40 390         3407 };
41              
42             subtype 'Bool'
43             => as 'Item'
44 55 100 100 55   584 => where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' }
      100        
45             => inline_as {
46 500     500   4557 '('
47             . '!defined(' . $_[1] . ') '
48             . '|| ' . $_[1] . ' eq "" '
49             . '|| (' . $_[1] . '."") eq "1" '
50             . '|| (' . $_[1] . '."") eq "0"'
51             . ')'
52 390         3269 };
53              
54             subtype 'Value'
55             => as 'Defined'
56 651     651   2393 => where { !ref($_) }
57             => inline_as {
58 2856     2856   77017 $_[0]->parent()->_inline_check($_[1])
59             . ' && !ref(' . $_[1] . ')'
60 390         3756 };
61              
62             subtype 'Ref'
63             => as 'Defined'
64 927     927   3549 => where { ref($_) }
65             # no need to call parent - ref also checks for definedness
66 390     402   3322 => inline_as { 'ref(' . $_[1] . ')' };
  402         2795  
67              
68             subtype 'Str'
69             => as 'Value'
70 535 100   535   2407 => where { ref(\$_) eq 'SCALAR' || ref(\(my $val = $_)) eq 'SCALAR' }
71             => inline_as {
72 1263     1263   36113 $_[0]->parent()->_inline_check($_[1])
73             . ' && ('
74             . 'ref(\\' . $_[1] . ') eq "SCALAR"'
75             . ' || ref(\\(my $val = ' . $_[1] . ')) eq "SCALAR"'
76             . ')'
77 390         3398 };
78              
79 390         2742 my $value_type = Moose::Util::TypeConstraints::find_type_constraint('Value');
80             subtype 'Num'
81             => as 'Str'
82             => where {
83 205     205   344 my $val = $_;
84 205 100       1473 ($val =~ /\A[+-]?[0-9]+\z/) ||
85             ( $val =~ /\A(?:[+-]?) # matches optional +- in the beginning
86             (?=[0-9]|\.[0-9]) # matches previous +- only if there is something like 3 or .3
87             [0-9]* # matches 0-9 zero or more times
88             (?:\.[0-9]+)? # matches optional .89 or nothing
89             (?:[Ee](?:[+-]?[0-9]+))? # matches E1 or e1 or e-1 or e+1 etc
90             \z/x );
91             }
92             => inline_as {
93             # the long Str tests are redundant here
94             #storing $_[1] in a temporary value,
95             #so that $_[1] won't get converted to a string for regex match
96             #see t/attributes/numeric_defaults.t for more details
97 415     415   2730 'my $val = '.$_[1].';'.
98             $value_type->_inline_check('$val')
99             .' && ( $val =~ /\A[+-]?[0-9]+\z/ || '
100             . '$val =~ /\A(?:[+-]?) # matches optional +- in the beginning
101             (?=[0-9]|\.[0-9]) # matches previous +- only if there is something like 3 or .3
102             [0-9]* # matches 0-9 zero or more times
103             (?:\.[0-9]+)? # matches optional .89 or nothing
104             (?:[Ee](?:[+-]?[0-9]+))? # matches E1 or e1 or e-1 or e+1 etc
105             \z/x ); '
106 390         2914 };
107              
108             subtype 'Int'
109             => as 'Num'
110 184     184   830 => where { (my $val = $_) =~ /\A-?[0-9]+\z/ }
111             => inline_as {
112 777     777   3629 $value_type->_inline_check($_[1])
113             . ' && (my $val = ' . $_[1] . ') =~ /\A-?[0-9]+\z/'
114 390         3462 };
115              
116             subtype 'CodeRef'
117             => as 'Ref'
118 12     12   97 => where { ref($_) eq 'CODE' }
119 390     417   3780 => inline_as { 'ref(' . $_[1] . ') eq "CODE"' };
  417         3124  
120              
121             subtype 'RegexpRef'
122             => as 'Ref'
123             => where( \&_RegexpRef )
124             => inline_as {
125 399     399   3027 'Moose::Util::TypeConstraints::Builtins::_RegexpRef(' . $_[1] . ')'
126 390         2837 };
127              
128             subtype 'GlobRef'
129             => as 'Ref'
130 12     12   81 => where { ref($_) eq 'GLOB' }
131 390     399   3417 => inline_as { 'ref(' . $_[1] . ') eq "GLOB"' };
  399         2883  
132              
133             # NOTE: scalar filehandles are GLOB refs, but a GLOB ref is not always a
134             # filehandle
135             subtype 'FileHandle'
136             => as 'Ref'
137             => where {
138 12 100 100 12   205 (ref($_) eq "GLOB" && Scalar::Util::openhandle($_))
      100        
139             || (blessed($_) && $_->isa("IO::Handle"));
140             }
141             => inline_as {
142 399     399   3827 '(ref(' . $_[1] . ') eq "GLOB" '
143             . '&& Scalar::Util::openhandle(' . $_[1] . ')) '
144             . '|| (Scalar::Util::blessed(' . $_[1] . ') '
145             . '&& ' . $_[1] . '->isa("IO::Handle"))'
146 390         3926 };
147              
148             subtype 'Object'
149             => as 'Ref'
150 121     121   669 => where { blessed($_) }
151 390     493   3978 => inline_as { 'Scalar::Util::blessed(' . $_[1] . ')' };
  493         3969  
152              
153             subtype 'ClassName'
154             => as 'Str'
155 28     28   246 => where { is_class_loaded($_) }
156             # the long Str tests are redundant here
157 390     801   3767 => inline_as { 'Class::Load::is_class_loaded(' . $_[1] . ')' };
  801         6474  
158              
159             subtype 'RoleName'
160             => as 'ClassName'
161             => where {
162 3   100 3   22 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
163             }
164             => inline_as {
165 400     400   12010 $_[0]->parent()->_inline_check($_[1])
166             . ' && do {'
167             . 'my $meta = Class::MOP::class_of(' . $_[1] . ');'
168             . '$meta && $meta->isa("Moose::Meta::Role");'
169             . '}'
170 390         3709 };
171              
172             $registry->add_type_constraint(
173             Moose::Meta::TypeConstraint::Parameterizable->new(
174             name => 'ScalarRef',
175             package_defined_in => __PACKAGE__,
176             parent =>
177             Moose::Util::TypeConstraints::find_type_constraint('Ref'),
178 12 100   12   120 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
179             constraint_generator => sub {
180 1     1   3 my $type_parameter = shift;
181 1         37 my $check = $type_parameter->_compiled_type_constraint;
182             return sub {
183 0         0 return $check->( ${$_} );
  0         0  
184 1         19 };
185             },
186             inlined => sub {
187 399     399   4138 'ref(' . $_[1] . ') eq "SCALAR" '
188             . '|| ref(' . $_[1] . ') eq "REF"'
189             },
190             inline_generator => sub {
191 2     2   4 my $self = shift;
192 2         6 my $type_parameter = shift;
193 2         3 my $val = shift;
194 2         14 '(ref(' . $val . ') eq "SCALAR" || ref(' . $val . ') eq "REF") '
195             . '&& ' . $type_parameter->_inline_check('${(' . $val . ')}')
196             },
197             )
198 390         3021 );
199              
200             $registry->add_type_constraint(
201             Moose::Meta::TypeConstraint::Parameterizable->new(
202             name => 'ArrayRef',
203             package_defined_in => __PACKAGE__,
204             parent =>
205             Moose::Util::TypeConstraints::find_type_constraint('Ref'),
206 448     448   1361 constraint => sub { ref($_) eq 'ARRAY' },
207             constraint_generator => sub {
208 108     108   359 my $type_parameter = shift;
209 108         4147 my $check = $type_parameter->_compiled_type_constraint;
210             return sub {
211 36         77 foreach my $x (@$_) {
212 89 100       1861 ( $check->($x) ) || return;
213             }
214 28         297 1;
215             }
216 108         1245 },
217 483     483   4128 inlined => sub { 'ref(' . $_[1] . ') eq "ARRAY"' },
218             inline_generator => sub {
219 221     221   563 my $self = shift;
220 221         439 my $type_parameter = shift;
221 221         419 my $val = shift;
222              
223 221         1319 'do {'
224             . 'my $check = ' . $val . ';'
225             . 'ref($check) eq "ARRAY" '
226             . '&& &List::Util::all('
227             . 'sub { ' . $type_parameter->_inline_check('$_') . ' }, '
228             . '@{$check}'
229             . ')'
230             . '}';
231             },
232             )
233 390         2397 );
234              
235             $registry->add_type_constraint(
236             Moose::Meta::TypeConstraint::Parameterizable->new(
237             name => 'HashRef',
238             package_defined_in => __PACKAGE__,
239             parent =>
240             Moose::Util::TypeConstraints::find_type_constraint('Ref'),
241 141     141   498 constraint => sub { ref($_) eq 'HASH' },
242             constraint_generator => sub {
243 20     20   56 my $type_parameter = shift;
244 20         728 my $check = $type_parameter->_compiled_type_constraint;
245             return sub {
246 115         331 foreach my $x ( values %$_ ) {
247 180 100       4077 ( $check->($x) ) || return;
248             }
249 95         1046 1;
250             }
251 20         187 },
252 561     561   4659 inlined => sub { 'ref(' . $_[1] . ') eq "HASH"' },
253             inline_generator => sub {
254 85     85   169 my $self = shift;
255 85         155 my $type_parameter = shift;
256 85         161 my $val = shift;
257              
258 85         379 'do {'
259             . 'my $check = ' . $val . ';'
260             . 'ref($check) eq "HASH" '
261             . '&& &List::Util::all('
262             . 'sub { ' . $type_parameter->_inline_check('$_') . ' }, '
263             . 'values %{$check}'
264             . ')'
265             . '}';
266             },
267             )
268 390         2497 );
269              
270             $registry->add_type_constraint(
271             Moose::Meta::TypeConstraint::Parameterizable->new(
272             name => 'Maybe',
273             package_defined_in => __PACKAGE__,
274             parent =>
275             Moose::Util::TypeConstraints::find_type_constraint('Item'),
276 25     25   66 constraint => sub {1},
277             constraint_generator => sub {
278 13     13   36 my $type_parameter = shift;
279 13         498 my $check = $type_parameter->_compiled_type_constraint;
280             return sub {
281 0 0 0     0 return 1 if not( defined($_) ) || $check->($_);
282 0         0 return;
283             }
284 13         109 },
285 399     399   2561 inlined => sub {'1'},
286             inline_generator => sub {
287 28     28   65 my $self = shift;
288 28         49 my $type_parameter = shift;
289 28         49 my $val = shift;
290 28         126 '!defined(' . $val . ') '
291             . '|| (' . $type_parameter->_inline_check($val) . ')'
292             },
293             )
294 390         2687 );
295             }
296              
297             1;
298              
299             __END__
300              
301             =pod
302              
303             =for pod_coverage_needs_some_pod
304              
305             =cut