line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Type::Params; |
2
|
|
|
|
|
|
|
|
3
|
57
|
|
|
57
|
|
230154
|
use 5.008001; |
|
57
|
|
|
|
|
247
|
|
4
|
57
|
|
|
57
|
|
334
|
use strict; |
|
57
|
|
|
|
|
119
|
|
|
57
|
|
|
|
|
1313
|
|
5
|
57
|
|
|
57
|
|
303
|
use warnings; |
|
57
|
|
|
|
|
116
|
|
|
57
|
|
|
|
|
2764
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
BEGIN { |
8
|
57
|
|
|
57
|
|
231
|
$Type::Params::AUTHORITY = 'cpan:TOBYINK'; |
9
|
57
|
|
|
|
|
2218
|
$Type::Params::VERSION = '2.003_000'; |
10
|
|
|
|
|
|
|
} |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
$Type::Params::VERSION =~ tr/_//d; |
13
|
|
|
|
|
|
|
|
14
|
57
|
|
|
57
|
|
406
|
use B qw(); |
|
57
|
|
|
|
|
131
|
|
|
57
|
|
|
|
|
1436
|
|
15
|
57
|
|
|
57
|
|
13041
|
use Eval::TypeTiny qw( eval_closure set_subname ); |
|
57
|
|
|
|
|
154
|
|
|
57
|
|
|
|
|
393
|
|
16
|
57
|
|
|
57
|
|
29965
|
use Scalar::Util qw( refaddr ); |
|
57
|
|
|
|
|
141
|
|
|
57
|
|
|
|
|
3183
|
|
17
|
57
|
|
|
57
|
|
10927
|
use Error::TypeTiny; |
|
57
|
|
|
|
|
145
|
|
|
57
|
|
|
|
|
1665
|
|
18
|
57
|
|
|
57
|
|
14409
|
use Error::TypeTiny::Assertion; |
|
57
|
|
|
|
|
148
|
|
|
57
|
|
|
|
|
1570
|
|
19
|
57
|
|
|
57
|
|
22586
|
use Error::TypeTiny::WrongNumberOfParameters; |
|
57
|
|
|
|
|
187
|
|
|
57
|
|
|
|
|
1697
|
|
20
|
57
|
|
|
57
|
|
15286
|
use Types::Standard (); |
|
57
|
|
|
|
|
227
|
|
|
57
|
|
|
|
|
1479
|
|
21
|
57
|
|
|
57
|
|
328
|
use Types::TypeTiny (); |
|
57
|
|
|
|
|
113
|
|
|
57
|
|
|
|
|
44742
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
require Exporter::Tiny; |
24
|
|
|
|
|
|
|
our @ISA = 'Exporter::Tiny'; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
our @EXPORT = qw( |
27
|
|
|
|
|
|
|
compile compile_named |
28
|
|
|
|
|
|
|
); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
our @EXPORT_OK = qw( |
31
|
|
|
|
|
|
|
compile_named_oo |
32
|
|
|
|
|
|
|
validate validate_named |
33
|
|
|
|
|
|
|
multisig |
34
|
|
|
|
|
|
|
Invocant ArgsObject |
35
|
|
|
|
|
|
|
wrap_subs wrap_methods |
36
|
|
|
|
|
|
|
signature signature_for |
37
|
|
|
|
|
|
|
); |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( |
40
|
|
|
|
|
|
|
compile => [ qw( compile compile_named compile_named_oo ) ], |
41
|
|
|
|
|
|
|
wrap => [ qw( wrap_subs wrap_methods ) ], |
42
|
|
|
|
|
|
|
sigs => [ qw( signature signature_for ) ], |
43
|
|
|
|
|
|
|
validate => [ qw( validate validate_named ) ], |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
v1 => [ qw( compile compile_named ) ], # Old default |
46
|
|
|
|
|
|
|
v2 => [ qw( signature signature_for ) ], # New recommendation |
47
|
|
|
|
|
|
|
); |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
{ |
50
|
|
|
|
|
|
|
my $Invocant; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub Invocant () { |
53
|
1
|
|
33
|
1
|
1
|
760
|
$Invocant ||= do { |
54
|
1
|
|
|
|
|
478
|
require Type::Tiny::Union; |
55
|
1
|
|
|
|
|
5
|
'Type::Tiny::Union'->new( |
56
|
|
|
|
|
|
|
name => 'Invocant', |
57
|
|
|
|
|
|
|
type_constraints => [ |
58
|
|
|
|
|
|
|
Types::Standard::Object(), |
59
|
|
|
|
|
|
|
Types::Standard::ClassName(), |
60
|
|
|
|
|
|
|
], |
61
|
|
|
|
|
|
|
); |
62
|
|
|
|
|
|
|
}; |
63
|
|
|
|
|
|
|
} #/ sub Invocant |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
my $ArgsObject; |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub ArgsObject (;@) { |
68
|
5
|
|
66
|
5
|
1
|
848
|
$ArgsObject ||= do { |
69
|
|
|
|
|
|
|
'Type::Tiny'->new( |
70
|
|
|
|
|
|
|
name => 'ArgsObject', |
71
|
|
|
|
|
|
|
parent => Types::Standard::Object(), |
72
|
|
|
|
|
|
|
constraint => q{ ref($_) =~ qr/^Type::Params::OO::/ }, |
73
|
|
|
|
|
|
|
constraint_generator => sub { |
74
|
3
|
|
|
3
|
|
13
|
my $param = Types::Standard::assert_Str( shift ); |
75
|
3
|
0
|
|
|
|
31
|
sub { defined( $_->{'~~caller'} ) and $_->{'~~caller'} eq $param }; |
|
0
|
|
|
|
|
0
|
|
76
|
|
|
|
|
|
|
}, |
77
|
|
|
|
|
|
|
inline_generator => sub { |
78
|
3
|
|
|
3
|
|
9
|
my $param = shift; |
79
|
3
|
|
|
|
|
10
|
my $quoted = B::perlstring( $param ); |
80
|
|
|
|
|
|
|
sub { |
81
|
3
|
|
|
|
|
8
|
my $var = pop; |
82
|
|
|
|
|
|
|
return ( |
83
|
3
|
|
|
|
|
10
|
Types::Standard::Object()->inline_check( $var ), |
84
|
|
|
|
|
|
|
sprintf( q{ ref(%s) =~ qr/^Type::Params::OO::/ }, $var ), |
85
|
|
|
|
|
|
|
sprintf( |
86
|
|
|
|
|
|
|
q{ do { use Scalar::Util (); Scalar::Util::reftype(%s) eq 'HASH' } }, $var |
87
|
|
|
|
|
|
|
), |
88
|
|
|
|
|
|
|
sprintf( |
89
|
|
|
|
|
|
|
q{ defined((%s)->{'~~caller'}) && ((%s)->{'~~caller'} eq %s) }, $var, $var, |
90
|
|
|
|
|
|
|
$quoted |
91
|
|
|
|
|
|
|
), |
92
|
|
|
|
|
|
|
); |
93
|
3
|
|
|
|
|
22
|
}; |
94
|
|
|
|
|
|
|
}, |
95
|
2
|
|
|
|
|
20
|
); |
96
|
|
|
|
|
|
|
}; |
97
|
|
|
|
|
|
|
|
98
|
5
|
50
|
|
|
|
66
|
@_ ? $ArgsObject->parameterize( @{ $_[0] } ) : $ArgsObject; |
|
0
|
|
|
|
|
0
|
|
99
|
|
|
|
|
|
|
} #/ sub ArgsObject (;@) |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
&Scalar::Util::set_prototype( \&ArgsObject, ';$' ) |
102
|
|
|
|
|
|
|
if Eval::TypeTiny::NICE_PROTOTYPES; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub signature { |
106
|
257
|
100
|
|
257
|
1
|
12251
|
if ( @_ % 2 ) { |
107
|
1
|
|
|
|
|
8
|
require Error::TypeTiny; |
108
|
1
|
|
|
|
|
5
|
Error::TypeTiny::croak( "Expected even-sized list of arguments" ); |
109
|
|
|
|
|
|
|
} |
110
|
256
|
|
|
|
|
938
|
my ( %opts ) = @_; |
111
|
|
|
|
|
|
|
|
112
|
256
|
|
66
|
|
|
3445
|
my $for = [ caller( 1 + ( $opts{caller_level} || 0 ) ) ]->[3] || ( ( $opts{package} || '__ANON__' ) . '::__ANON__' ); |
113
|
256
|
|
|
|
|
2324
|
my ( $pkg, $sub ) = ( $for =~ /^(.+)::(\w+)$/ ); |
114
|
256
|
|
66
|
|
|
1548
|
$opts{package} ||= $pkg; |
115
|
256
|
|
66
|
|
|
1301
|
$opts{subname} ||= $sub; |
116
|
|
|
|
|
|
|
|
117
|
256
|
|
|
|
|
25781
|
require Type::Params::Signature; |
118
|
256
|
|
|
|
|
1848
|
'Type::Params::Signature'->new_from_v2api( \%opts )->return_wanted; |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
sub signature_for { |
122
|
16
|
100
|
|
16
|
1
|
5272
|
if ( not @_ % 2 ) { |
123
|
1
|
|
|
|
|
11
|
require Error::TypeTiny; |
124
|
1
|
|
|
|
|
5
|
Error::TypeTiny::croak( "Expected odd-sized list of arguments; did you forget the function name?" ); |
125
|
|
|
|
|
|
|
} |
126
|
15
|
|
|
|
|
87
|
my ( $function, %opts ) = @_; |
127
|
15
|
|
66
|
|
|
217
|
my $package = $opts{package} || caller( $opts{caller_level} || 0 ); |
128
|
|
|
|
|
|
|
|
129
|
15
|
100
|
|
|
|
84
|
if ( ref($function) eq 'ARRAY' ) { |
130
|
2
|
|
|
|
|
6
|
$opts{package} = $package; |
131
|
2
|
|
|
|
|
17
|
signature_for( $_, %opts ) for @$function; |
132
|
2
|
|
|
|
|
10
|
return; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
13
|
50
|
|
|
|
103
|
my $fullname = ( $function =~ /::/ ) ? $function : "$package\::$function"; |
136
|
13
|
|
66
|
|
|
162
|
$opts{package} ||= $package; |
137
|
13
|
50
|
33
|
|
|
101
|
$opts{subname} ||= ( $function =~ /::(\w+)$/ ) ? $1 : $function; |
138
|
57
|
100
|
100
|
57
|
|
503
|
$opts{goto_next} ||= do { no strict 'refs'; exists(&$fullname) ? \&$fullname : undef; }; |
|
57
|
|
|
|
|
168
|
|
|
57
|
|
|
|
|
11540
|
|
|
13
|
|
|
|
|
82
|
|
|
12
|
|
|
|
|
119
|
|
139
|
13
|
100
|
|
|
|
65
|
if ( $opts{method} ) { |
140
|
7
|
|
66
|
|
|
26
|
$opts{goto_next} ||= eval { $package->can( $opts{subname} ) }; |
|
1
|
|
|
|
|
11
|
|
141
|
|
|
|
|
|
|
} |
142
|
13
|
100
|
100
|
|
|
71
|
if ( $opts{fallback} and not $opts{goto_next} ) { |
143
|
1
|
50
|
|
0
|
|
8
|
$opts{goto_next} = ref( $opts{fallback} ) ? $opts{fallback} : sub {}; |
144
|
|
|
|
|
|
|
} |
145
|
13
|
100
|
|
|
|
47
|
if ( not $opts{goto_next} ) { |
146
|
1
|
|
|
|
|
7
|
require Error::TypeTiny; |
147
|
1
|
|
|
|
|
6
|
return Error::TypeTiny::croak( "Function '$function' not found to wrap!" ); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
12
|
|
|
|
|
4876
|
require Type::Params::Signature; |
151
|
12
|
|
|
|
|
168
|
my $sig = 'Type::Params::Signature'->new_from_v2api( \%opts ); |
152
|
|
|
|
|
|
|
# Delay compilation |
153
|
10
|
|
|
|
|
37
|
my $compiled; |
154
|
|
|
|
|
|
|
my $coderef = sub { |
155
|
10
|
|
33
|
10
|
|
3278
|
$compiled ||= $sig->coderef->compile; |
|
|
|
|
11
|
|
|
|
156
|
|
|
|
|
|
|
|
157
|
57
|
|
|
57
|
|
450
|
no strict 'refs'; |
|
57
|
|
|
|
|
145
|
|
|
57
|
|
|
|
|
1998
|
|
158
|
57
|
|
|
57
|
|
381
|
no warnings 'redefine'; |
|
57
|
|
|
|
|
136
|
|
|
57
|
|
|
|
|
4818
|
|
159
|
10
|
|
|
|
|
65
|
*$fullname = set_subname( $fullname, $compiled ); |
160
|
|
|
|
|
|
|
|
161
|
10
|
|
|
|
|
204
|
goto( $compiled ); |
162
|
10
|
|
|
|
|
109
|
}; |
163
|
|
|
|
|
|
|
|
164
|
57
|
|
|
57
|
|
478
|
no strict 'refs'; |
|
57
|
|
|
|
|
170
|
|
|
57
|
|
|
|
|
1890
|
|
165
|
57
|
|
|
57
|
|
351
|
no warnings 'redefine'; |
|
57
|
|
|
|
|
128
|
|
|
57
|
|
|
|
|
51668
|
|
166
|
10
|
|
|
|
|
94
|
*$fullname = set_subname( $fullname, $coderef ); |
167
|
|
|
|
|
|
|
|
168
|
10
|
|
|
|
|
6742
|
return; |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub compile { |
172
|
83
|
|
|
83
|
1
|
41675
|
my @args = @_; |
173
|
83
|
|
|
|
|
303
|
@_ = ( positional => \@args ); |
174
|
83
|
|
|
|
|
411
|
goto \&signature; |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub compile_named { |
178
|
85
|
|
|
85
|
1
|
80304
|
my @args = @_; |
179
|
85
|
|
|
|
|
322
|
@_ = ( bless => 0, named => \@args ); |
180
|
85
|
|
|
|
|
355
|
goto \&signature; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
sub compile_named_oo { |
184
|
20
|
|
|
20
|
1
|
17730
|
my @args = @_; |
185
|
20
|
|
|
|
|
74
|
@_ = ( bless => 1, named => \@args ); |
186
|
20
|
|
|
|
|
122
|
goto \&signature; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
# Would be faster to inline this into validate and validate_named, but |
190
|
|
|
|
|
|
|
# that would complicate them. :/ |
191
|
|
|
|
|
|
|
sub _mk_key { |
192
|
933
|
|
|
933
|
|
1375
|
local $_; |
193
|
|
|
|
|
|
|
join ':', map { |
194
|
933
|
|
|
|
|
1639
|
Types::Standard::is_HashRef( $_ ) ? do { |
195
|
488
|
|
|
|
|
1432
|
my %h = %$_; |
196
|
488
|
|
|
|
|
1390
|
sprintf( '{%s}', _mk_key( map { ; $_ => $h{$_} } sort keys %h ) ); |
|
610
|
|
|
|
|
1770
|
|
197
|
|
|
|
|
|
|
} : |
198
|
4623
|
50
|
|
|
|
101201
|
Types::TypeTiny::is_TypeTiny( $_ ) ? sprintf( 'TYPE=%s', $_->{uniq} ) : |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
199
|
|
|
|
|
|
|
Types::Standard::is_Ref( $_ ) ? sprintf( 'REF=%s', refaddr( $_ ) ) : |
200
|
|
|
|
|
|
|
Types::Standard::is_Undef( $_ ) ? sprintf( 'UNDEF' ) : |
201
|
|
|
|
|
|
|
B::perlstring( $_ ) |
202
|
|
|
|
|
|
|
} @_; |
203
|
|
|
|
|
|
|
} #/ sub _mk_key |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
{ |
206
|
|
|
|
|
|
|
my %compiled; |
207
|
|
|
|
|
|
|
sub validate { |
208
|
15
|
|
|
15
|
1
|
422
|
my $arg = shift; |
209
|
|
|
|
|
|
|
my $sub = ( |
210
|
|
|
|
|
|
|
$compiled{ _mk_key( @_ ) } ||= signature( |
211
|
|
|
|
|
|
|
caller_level => 1, |
212
|
15
|
50
|
66
|
|
|
49
|
%{ ref( $_[0] ) eq 'HASH' ? shift( @_ ) : +{} }, |
|
9
|
|
|
|
|
102
|
|
213
|
|
|
|
|
|
|
positional => [ @_ ], |
214
|
|
|
|
|
|
|
) |
215
|
|
|
|
|
|
|
); |
216
|
15
|
|
|
|
|
149
|
@_ = @$arg; |
217
|
15
|
|
|
|
|
60
|
goto $sub; |
218
|
|
|
|
|
|
|
} #/ sub validate |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
{ |
222
|
|
|
|
|
|
|
my %compiled; |
223
|
|
|
|
|
|
|
sub validate_named { |
224
|
430
|
|
|
430
|
1
|
284848
|
my $arg = shift; |
225
|
|
|
|
|
|
|
my $sub = ( |
226
|
|
|
|
|
|
|
$compiled{ _mk_key( @_ ) } ||= signature( |
227
|
|
|
|
|
|
|
caller_level => 1, |
228
|
|
|
|
|
|
|
bless => 0, |
229
|
430
|
100
|
66
|
|
|
1125
|
%{ ref( $_[0] ) eq 'HASH' ? shift( @_ ) : +{} }, |
|
28
|
|
|
|
|
202
|
|
230
|
|
|
|
|
|
|
named => [ @_ ], |
231
|
|
|
|
|
|
|
) |
232
|
|
|
|
|
|
|
); |
233
|
430
|
|
|
|
|
1714
|
@_ = @$arg; |
234
|
430
|
|
|
|
|
1502
|
goto $sub; |
235
|
|
|
|
|
|
|
} #/ sub validate_named |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
sub multisig { |
239
|
7
|
100
|
|
7
|
1
|
71
|
my %options = ( ref( $_[0] ) eq "HASH" ) ? %{ +shift } : (); |
|
3
|
|
|
|
|
17
|
|
240
|
7
|
|
|
|
|
36
|
signature( |
241
|
|
|
|
|
|
|
%options, |
242
|
|
|
|
|
|
|
multi => \@_, |
243
|
|
|
|
|
|
|
); |
244
|
|
|
|
|
|
|
} #/ sub multisig |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
sub wrap_methods { |
247
|
2
|
50
|
|
2
|
1
|
19
|
my $opts = ref( $_[0] ) eq 'HASH' ? shift : {}; |
248
|
2
|
|
33
|
|
|
16
|
$opts->{caller} ||= caller; |
249
|
2
|
|
|
|
|
3
|
$opts->{skip_invocant} = 1; |
250
|
2
|
|
|
|
|
4
|
$opts->{use_can} = 1; |
251
|
2
|
|
|
|
|
7
|
unshift @_, $opts; |
252
|
2
|
|
|
|
|
7
|
goto \&_wrap_subs; |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
sub wrap_subs { |
256
|
1
|
50
|
|
1
|
1
|
4
|
my $opts = ref( $_[0] ) eq 'HASH' ? shift : {}; |
257
|
1
|
|
33
|
|
|
10
|
$opts->{caller} ||= caller; |
258
|
1
|
|
|
|
|
3
|
$opts->{skip_invocant} = 0; |
259
|
1
|
|
|
|
|
2
|
$opts->{use_can} = 0; |
260
|
1
|
|
|
|
|
4
|
unshift @_, $opts; |
261
|
1
|
|
|
|
|
5
|
goto \&_wrap_subs; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
sub _wrap_subs { |
265
|
3
|
|
|
3
|
|
6
|
my $opts = shift; |
266
|
3
|
|
|
|
|
11
|
while ( @_ ) { |
267
|
8
|
|
|
|
|
30
|
my ( $name, $proto ) = splice @_, 0, 2; |
268
|
8
|
50
|
|
|
|
51
|
my $fullname = ( $name =~ /::/ ) ? $name : sprintf( '%s::%s', $opts->{caller}, $name ); |
269
|
8
|
|
|
|
|
14
|
my $orig = do { |
270
|
57
|
|
|
57
|
|
502
|
no strict 'refs'; |
|
57
|
|
|
|
|
136
|
|
|
57
|
|
|
|
|
12797
|
|
271
|
|
|
|
|
|
|
exists &$fullname ? \&$fullname |
272
|
|
|
|
2
|
|
|
: $opts->{use_can} ? ( $opts->{caller}->can( $name ) || sub { } ) |
273
|
|
|
|
1
|
|
|
: sub { } |
274
|
8
|
100
|
100
|
|
|
94
|
}; |
|
|
100
|
|
|
|
|
|
275
|
8
|
|
|
|
|
15
|
my $new; |
276
|
8
|
100
|
|
|
|
21
|
if ( ref $proto eq 'CODE' ) { |
277
|
|
|
|
|
|
|
$new = $opts->{skip_invocant} |
278
|
|
|
|
|
|
|
? sub { |
279
|
4
|
|
|
4
|
|
24
|
my $s = shift; |
280
|
4
|
|
|
|
|
12
|
@_ = ( $s, &$proto ); |
281
|
2
|
|
|
|
|
102
|
goto $orig; |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
: sub { |
284
|
2
|
|
|
2
|
|
12
|
@_ = &$proto; |
285
|
1
|
|
|
|
|
59
|
goto $orig; |
286
|
2
|
100
|
|
|
|
35
|
}; |
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
else { |
289
|
|
|
|
|
|
|
$new = compile( |
290
|
|
|
|
|
|
|
{ |
291
|
|
|
|
|
|
|
'package' => $opts->{caller}, |
292
|
|
|
|
|
|
|
'subname' => $name, |
293
|
|
|
|
|
|
|
'goto_next' => $orig, |
294
|
6
|
100
|
|
|
|
38
|
'head' => $opts->{skip_invocant} ? 1 : 0, |
295
|
|
|
|
|
|
|
}, |
296
|
|
|
|
|
|
|
@$proto, |
297
|
|
|
|
|
|
|
); |
298
|
|
|
|
|
|
|
} |
299
|
57
|
|
|
57
|
|
467
|
no strict 'refs'; |
|
57
|
|
|
|
|
146
|
|
|
57
|
|
|
|
|
1941
|
|
300
|
57
|
|
|
57
|
|
359
|
no warnings 'redefine'; |
|
57
|
|
|
|
|
119
|
|
|
57
|
|
|
|
|
6178
|
|
301
|
8
|
|
|
|
|
92
|
*$fullname = set_subname( $fullname, $new ); |
302
|
|
|
|
|
|
|
} #/ while ( @_ ) |
303
|
3
|
|
|
|
|
12
|
1; |
304
|
|
|
|
|
|
|
} #/ sub _wrap_subs |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
1; |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
__END__ |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=pod |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=encoding utf-8 |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=for stopwords evals invocant |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
=head1 NAME |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
Type::Params - sub signature validation using Type::Tiny type constraints and coercions |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=head1 SYNOPSIS |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
use v5.20; |
323
|
|
|
|
|
|
|
use strict; |
324
|
|
|
|
|
|
|
use warnings; |
325
|
|
|
|
|
|
|
use experimental 'signatures'; |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
package Horse { |
328
|
|
|
|
|
|
|
use Moo; |
329
|
|
|
|
|
|
|
use Types::Standard qw( Object ); |
330
|
|
|
|
|
|
|
use Type::Params -sigs; |
331
|
|
|
|
|
|
|
use namespace::autoclean; |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
...; # define attributes, etc |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
signature_for add_child => ( |
336
|
|
|
|
|
|
|
method => 1, |
337
|
|
|
|
|
|
|
positional => [ Object ], |
338
|
|
|
|
|
|
|
); |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
sub add_child ( $self, $child ) { |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
push @{ $self->children }, $child; |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
return $self; |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
package main; |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
my $boldruler = Horse->new; |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
$boldruler->add_child( Horse->new ); |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
$boldruler->add_child( 123 ); # dies (123 is not an Object!) |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
=head1 STATUS |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
This module is covered by the |
359
|
|
|
|
|
|
|
L<Type-Tiny stability policy|Type::Tiny::Manual::Policies/"STABILITY">. |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=head1 DESCRIPTION |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
This documents the details of the L<Type::Params> package. |
364
|
|
|
|
|
|
|
L<Type::Tiny::Manual> is a better starting place if you're new. |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
Type::Params uses L<Type::Tiny> constraints to validate the parameters to a |
367
|
|
|
|
|
|
|
sub. It takes the slightly unorthodox approach of separating validation |
368
|
|
|
|
|
|
|
into two stages: |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
=over |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=item 1. |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
Compiling the parameter specification into a coderef; then |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=item 2. |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
Using the coderef to validate parameters. |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=back |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
The first stage is slow (it might take a couple of milliseconds), but you |
383
|
|
|
|
|
|
|
only need to do it the first time the sub is called. The second stage is |
384
|
|
|
|
|
|
|
fast; according to my benchmarks faster even than the XS version of |
385
|
|
|
|
|
|
|
L<Params::Validate>. |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=head1 MODERN API |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
The modern API can be exported using: |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
use Type::Params -sigs; |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
Or: |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
use Type::Params -v2; |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
Or by requesting functions by name: |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
use Type::Params qw( signature signature_for ); |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=head2 C<< signature( %spec ) >> |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
The C<signature> function takes a specification for your function's |
404
|
|
|
|
|
|
|
signature and returns a coderef. You then call the coderef in list |
405
|
|
|
|
|
|
|
context, passing C<< @_ >> to it. The coderef will check, coerce, and |
406
|
|
|
|
|
|
|
apply other procedures to the values, and return the tidied values, |
407
|
|
|
|
|
|
|
or die with an error. |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
The usual way of using it is: |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
sub your_function { |
412
|
|
|
|
|
|
|
state $signature = signature( ... ); |
413
|
|
|
|
|
|
|
my ( $arg1, $arg2, $arg3 ) = $signature->( @_ ); |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
...; |
416
|
|
|
|
|
|
|
} |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
Perl allows a slightly archaic way of calling coderefs without using |
419
|
|
|
|
|
|
|
parentheses, which may be slightly faster at the cost of being more |
420
|
|
|
|
|
|
|
obscure: |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
sub your_function { |
423
|
|
|
|
|
|
|
state $signature = signature( ... ); |
424
|
|
|
|
|
|
|
my ( $arg1, $arg2, $arg3 ) = &$signature; |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
...; |
427
|
|
|
|
|
|
|
} |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
If you need to support Perl 5.8, which didn't have the C<state> keyword: |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
my $__your_function_sig; |
432
|
|
|
|
|
|
|
sub your_function { |
433
|
|
|
|
|
|
|
$__your_function_sig ||= signature( ... ); |
434
|
|
|
|
|
|
|
my ( $arg1, $arg2, $arg3 ) = $__your_function_sig->( @_ ); |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
...; |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
One important thing to note is how the signature is only compiled into a |
440
|
|
|
|
|
|
|
coderef the first time your function gets called, and thereafter will be |
441
|
|
|
|
|
|
|
reused. |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=head3 Signature Specification Options |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
The signature specification is a hash which must contain either a |
446
|
|
|
|
|
|
|
C<positional>, C<named>, or C<multiple> key indicating whether your |
447
|
|
|
|
|
|
|
function takes positional parameters, named parameters, or supports |
448
|
|
|
|
|
|
|
multiple calling conventions, but may also include other options. |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=head4 C<< positional >> B<ArrayRef> |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
This is conceptually a list of type constraints, one for each positional |
453
|
|
|
|
|
|
|
parameter. For example, a signature for a function which accepts two |
454
|
|
|
|
|
|
|
integers: |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
signature( positional => [ Int, Int ] ) |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
However, each type constraint is optionally followed by a hashref of |
459
|
|
|
|
|
|
|
options which affect that parameter. For example: |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
signature( positional => [ |
462
|
|
|
|
|
|
|
Int, { default => 40 }, |
463
|
|
|
|
|
|
|
Int, { default => 2 }, |
464
|
|
|
|
|
|
|
] ) |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
Type constraints can instead be given as strings, which will be looked |
467
|
|
|
|
|
|
|
up using C<dwim_type> from L<Type::Utils>. |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
signature( positional => [ |
470
|
|
|
|
|
|
|
'Int', { default => 40 }, |
471
|
|
|
|
|
|
|
'Int', { default => 2 }, |
472
|
|
|
|
|
|
|
] ) |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
See the section below for more information on parameter options. |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
Optional parameters must follow required parameters, and can be specified |
477
|
|
|
|
|
|
|
using either the B<Optional> parameterizable type constraint, the |
478
|
|
|
|
|
|
|
C<optional> parameter option, or by providing a default. |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
signature( positional => [ |
481
|
|
|
|
|
|
|
Optional[Int], |
482
|
|
|
|
|
|
|
Int, { optional => !!1 }, |
483
|
|
|
|
|
|
|
Int, { default => 42 }, |
484
|
|
|
|
|
|
|
] ) |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
A single slurpy parameter may be provided at the end, using the B<Slurpy> |
487
|
|
|
|
|
|
|
parameterizable type constraint, or the C<slurpy> parameter option: |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
signature( positional => [ |
490
|
|
|
|
|
|
|
Int, |
491
|
|
|
|
|
|
|
Slurpy[ ArrayRef[Int] ], |
492
|
|
|
|
|
|
|
] ) |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
signature( positional => [ |
495
|
|
|
|
|
|
|
Int, |
496
|
|
|
|
|
|
|
ArrayRef[Int], { slurpy => !!1 }, |
497
|
|
|
|
|
|
|
] ) |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
The C<positional> option can also be abbreviated to C<pos>. |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
So C<< signature( pos => [...] ) >> can be used instead of the longer |
502
|
|
|
|
|
|
|
C<< signature( positional => [...] ) >>. |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
If a signature uses positional parameters, the values are returned by the |
505
|
|
|
|
|
|
|
coderef as a list: |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
sub add_numbers { |
508
|
|
|
|
|
|
|
state $sig = signature( positional => [ Num, Num ] ); |
509
|
|
|
|
|
|
|
my ( $num1, $num2 ) = $sig->( @_ ); |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
return $num1 + $num2; |
512
|
|
|
|
|
|
|
} |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
say add_numbers( 2, 3 ); # says 5 |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
=head4 C<< named >> B<ArrayRef> |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
This is conceptually a list of pairs of names and type constraints, one |
519
|
|
|
|
|
|
|
name+type pair for each positional parameter. For example, a signature for |
520
|
|
|
|
|
|
|
a function which accepts two integers: |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
signature( named => [ foo => Int, bar => Int ] ) |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
However, each type constraint is optionally followed by a hashref of |
525
|
|
|
|
|
|
|
options which affect that parameter. For example: |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
signature( named => [ |
528
|
|
|
|
|
|
|
foo => Int, { default => 40 }, |
529
|
|
|
|
|
|
|
bar => Int, { default => 2 }, |
530
|
|
|
|
|
|
|
] ) |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
Type constraints can instead be given as strings, which will be looked |
533
|
|
|
|
|
|
|
up using C<dwim_type> from L<Type::Utils>. |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
signature( named => [ |
536
|
|
|
|
|
|
|
foo => 'Int', { default => 40 }, |
537
|
|
|
|
|
|
|
bar => 'Int', { default => 2 }, |
538
|
|
|
|
|
|
|
] ) |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
Optional and slurpy parameters are allowed, but unlike positional parameters, |
541
|
|
|
|
|
|
|
they do not need to be at the end. |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
See the section below for more information on parameter options. |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
If a signature uses named parameters, the values are returned by the |
546
|
|
|
|
|
|
|
coderef as an object: |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
sub add_numbers { |
549
|
|
|
|
|
|
|
state $sig = signature( named => [ num1 => Num, num2 => Num ] ); |
550
|
|
|
|
|
|
|
my ( $arg ) = $sig->( @_ ); |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
return $arg->num1 + $arg->num2; |
553
|
|
|
|
|
|
|
} |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
say add_numbers( num1 => 2, num2 => 3 ); # says 5 |
556
|
|
|
|
|
|
|
say add_numbers( { num1 => 2, num2 => 3 } ); # also says 5 |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
=head4 C<< named_to_list >> B<< ArrayRef|Bool >> |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
The C<named_to_list> option is ignored for signatures using positional |
561
|
|
|
|
|
|
|
parameters, but for signatures using named parameters, allows them to |
562
|
|
|
|
|
|
|
be returned in a list instead of as an object: |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
sub add_numbers { |
565
|
|
|
|
|
|
|
state $sig = signature( |
566
|
|
|
|
|
|
|
named => [ num1 => Num, num2 => Num ], |
567
|
|
|
|
|
|
|
named_to_list => !!1, |
568
|
|
|
|
|
|
|
); |
569
|
|
|
|
|
|
|
my ( $num1, $num2 ) = $sig->( @_ ); |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
return $num1 + $num2; |
572
|
|
|
|
|
|
|
} |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
say add_numbers( num1 => 2, num2 => 3 ); # says 5 |
575
|
|
|
|
|
|
|
say add_numbers( { num1 => 2, num2 => 3 } ); # also says 5 |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
You can think of C<add_numbers> above as a function which takes named |
578
|
|
|
|
|
|
|
parameters from the outside, but receives positional parameters on the |
579
|
|
|
|
|
|
|
inside. |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
You can use an arrayref to specify the order the paramaters will be |
582
|
|
|
|
|
|
|
returned in. (By default they are returned in the order they were defined |
583
|
|
|
|
|
|
|
in.) |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
sub add_numbers { |
586
|
|
|
|
|
|
|
state $sig = signature( |
587
|
|
|
|
|
|
|
named => [ num1 => Num, num2 => Num ], |
588
|
|
|
|
|
|
|
named_to_list => [ qw( num2 num1 ) ], |
589
|
|
|
|
|
|
|
); |
590
|
|
|
|
|
|
|
my ( $num2, $num1 ) = $sig->( @_ ); |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
return $num1 + $num2; |
593
|
|
|
|
|
|
|
} |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
=head4 C<< head >> B<< Int|ArrayRef >> |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
C<head> provides an additional list of non-optional, positional parameters |
598
|
|
|
|
|
|
|
at the start of C<< @_ >>. This is often used for method calls. For example, |
599
|
|
|
|
|
|
|
if you wish to define a signature for: |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
$object->my_method( foo => 123, bar => 456 ); |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
You could write it as this: |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
sub my_method { |
606
|
|
|
|
|
|
|
state $signature = signature( |
607
|
|
|
|
|
|
|
head => [ Object ], |
608
|
|
|
|
|
|
|
named => [ foo => Optional[Int], bar => Optional[Int] ], |
609
|
|
|
|
|
|
|
); |
610
|
|
|
|
|
|
|
my ( $self, $arg ) = $signature->( @_ ); |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
...; |
613
|
|
|
|
|
|
|
} |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
If C<head> is set as a number instead of an arrayref, it is the number of |
616
|
|
|
|
|
|
|
additional arguments at the start: |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
sub my_method { |
619
|
|
|
|
|
|
|
state $signature = signature( |
620
|
|
|
|
|
|
|
head => 1, |
621
|
|
|
|
|
|
|
named => [ foo => Optional[Int], bar => Optional[Int] ], |
622
|
|
|
|
|
|
|
); |
623
|
|
|
|
|
|
|
my ( $self, $arg ) = $signature->( @_ ); |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
...; |
626
|
|
|
|
|
|
|
} |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
In this case, no type checking is performed on those additional arguments; |
629
|
|
|
|
|
|
|
it is just checked that they exist. |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
=head4 C<< tail >> B<< Int|ArrayRef >> |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
A C<tail> is like a C<head> except that it is for arguments at the I<end> |
634
|
|
|
|
|
|
|
of C<< @_ >>. |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
sub my_method { |
637
|
|
|
|
|
|
|
state $signature = signature( |
638
|
|
|
|
|
|
|
head => [ Object ], |
639
|
|
|
|
|
|
|
named => [ foo => Optional[Int], bar => Optional[Int] ], |
640
|
|
|
|
|
|
|
tail => [ CodeRef ], |
641
|
|
|
|
|
|
|
); |
642
|
|
|
|
|
|
|
my ( $self, $arg, $callback ) = $signature->( @_ ); |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
...; |
645
|
|
|
|
|
|
|
} |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
$object->my_method( foo => 123, bar => 456, sub { ... } ); |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
=head4 C<< method >> B<< Bool|TypeTiny >> |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
While C<head> can be used for method signatures, a more declarative way is |
652
|
|
|
|
|
|
|
to set C<< method => 1 >>. |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
If you wish to be specific that this is an object method, intended to be |
655
|
|
|
|
|
|
|
called on blessed objects only, then you may use C<< method => Object >>, |
656
|
|
|
|
|
|
|
using the B<Object> type from L<Types::Standard>. If you wish to specify |
657
|
|
|
|
|
|
|
that it's a class method, then use C<< method => Str >>, using the B<Str> |
658
|
|
|
|
|
|
|
type from L<Types::Standard>. (C<< method => ClassName >> is perhaps |
659
|
|
|
|
|
|
|
clearer, but it's a slower check.) |
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
sub my_method { |
662
|
|
|
|
|
|
|
state $signature = signature( |
663
|
|
|
|
|
|
|
method => 1, |
664
|
|
|
|
|
|
|
named => [ foo => Optional[Int], bar => Optional[Int] ], |
665
|
|
|
|
|
|
|
); |
666
|
|
|
|
|
|
|
my ( $self, $arg ) = $signature->( @_ ); |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
...; |
669
|
|
|
|
|
|
|
} |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
If C<< method >> is true (or a type constraint) then any parameter |
672
|
|
|
|
|
|
|
defaults which are coderefs will be called as methods. |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
=head4 C<< description >> B<Str> |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
This is the description of the coderef that will show up in stack traces. |
677
|
|
|
|
|
|
|
It defaults to "parameter validation for X" where X is the caller sub name. |
678
|
|
|
|
|
|
|
Usually the default will be fine. |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
=head4 C<< package >> B<Str> |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
The package of the sub whose paramaters we're supposed to be checking. |
683
|
|
|
|
|
|
|
As well as showing up in stack traces, it's used by C<dwim_type> if you |
684
|
|
|
|
|
|
|
provide any type constraints as strings. |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
The default is probably fine, but if you're wrapping C<signature> so that |
687
|
|
|
|
|
|
|
you can check signatures on behalf of another package, you may need to |
688
|
|
|
|
|
|
|
provide it. |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
=head4 C<< subname >> B<Str> |
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
The name of the sub whose paramaters we're supposed to be checking. |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
The default is probably fine, but if you're wrapping C<signature> so that |
695
|
|
|
|
|
|
|
you can check signatures on behalf of another package, you may need to |
696
|
|
|
|
|
|
|
provide it. |
697
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
=head4 C<< caller_level >> B<Int> |
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
If you're wrapping C<signature> so that you can check signatures on behalf |
701
|
|
|
|
|
|
|
of another package, then setting C<caller_level> to 1 (or more, depending on |
702
|
|
|
|
|
|
|
the level of wrapping!) may be an alternative to manually setting the |
703
|
|
|
|
|
|
|
C<package> and C<subname>. |
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
=head4 C<< on_die >> B<< Maybe[CodeRef] >> |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
Usually when your coderef hits an error, it will throw an exception, which |
708
|
|
|
|
|
|
|
is a blessed L<Error::TypeTiny> object. |
709
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
If you provide an C<on_die> coderef, then instead the L<Error::TypeTiny> |
711
|
|
|
|
|
|
|
object will be passed to it. If the C<on_die> coderef returns something, |
712
|
|
|
|
|
|
|
then whatever it returns will be returned as your signature's parameters. |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
sub add_numbers { |
715
|
|
|
|
|
|
|
state $sig = signature( |
716
|
|
|
|
|
|
|
positional => [ Num, Num ], |
717
|
|
|
|
|
|
|
on_die => sub { |
718
|
|
|
|
|
|
|
my $error = shift; |
719
|
|
|
|
|
|
|
print "Existential crisis: $error\n"; |
720
|
|
|
|
|
|
|
exit( 1 ); |
721
|
|
|
|
|
|
|
}, |
722
|
|
|
|
|
|
|
); |
723
|
|
|
|
|
|
|
my ( $num1, $num2 ) = $sig->( @_ ); |
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
return $num1 + $num2; |
726
|
|
|
|
|
|
|
} |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
say add_numbers(); # has an existential crisis |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
This is probably not very useful. |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
=head4 C<< goto_next >> B<< Bool|CodeLike >> |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
This can be used for chaining coderefs. If you understand C<on_die>, it's |
735
|
|
|
|
|
|
|
more like an "on_live". |
736
|
|
|
|
|
|
|
|
737
|
|
|
|
|
|
|
sub add_numbers { |
738
|
|
|
|
|
|
|
state $sig = signature( |
739
|
|
|
|
|
|
|
positional => [ Num, Num ], |
740
|
|
|
|
|
|
|
goto_next => sub { |
741
|
|
|
|
|
|
|
my ( $num1, $num2 ) = @_; |
742
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
return $num1 + $num2; |
744
|
|
|
|
|
|
|
}, |
745
|
|
|
|
|
|
|
); |
746
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
my $sum = $sig->( @_ ); |
748
|
|
|
|
|
|
|
return $sum; |
749
|
|
|
|
|
|
|
} |
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
say add_numbers( 2, 3 ); # says 5 |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
If set to a true boolean instead of a coderef, has a slightly different |
754
|
|
|
|
|
|
|
behaviour: |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
sub add_numbers { |
757
|
|
|
|
|
|
|
state $sig = signature( |
758
|
|
|
|
|
|
|
positional => [ Num, Num ], |
759
|
|
|
|
|
|
|
goto_next => !!1, |
760
|
|
|
|
|
|
|
); |
761
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
my $sum = $sig->( |
763
|
|
|
|
|
|
|
sub { return $_[0] + $_[1] }, |
764
|
|
|
|
|
|
|
@_, |
765
|
|
|
|
|
|
|
); |
766
|
|
|
|
|
|
|
return $sum; |
767
|
|
|
|
|
|
|
} |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
say add_numbers( 2, 3 ); # says 5 |
770
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
This looks strange. Why would this be useful? Well, it works nicely with |
772
|
|
|
|
|
|
|
Moose's C<around> keyword. |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
sub add_numbers { |
775
|
|
|
|
|
|
|
return $_[1] + $_[2]; |
776
|
|
|
|
|
|
|
} |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
around add_numbers => signature( |
779
|
|
|
|
|
|
|
method => !!1, |
780
|
|
|
|
|
|
|
positional => [ Num, Num ], |
781
|
|
|
|
|
|
|
goto_next => !!1, |
782
|
|
|
|
|
|
|
package => __PACKAGE__, |
783
|
|
|
|
|
|
|
subname => 'add_numbers', |
784
|
|
|
|
|
|
|
); |
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
say __PACKAGE__->add_numbers( 2, 3 ); # says 5 |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
Note the way C<around> works in Moose is that it expects a wrapper coderef |
789
|
|
|
|
|
|
|
as its final argument. That wrapper coderef then expects to be given a |
790
|
|
|
|
|
|
|
reference to the original function as its first parameter. |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
This can allow, for example, a role to provide a signature wrapping |
793
|
|
|
|
|
|
|
a method defined in a class. |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
This is kind of complex, and you're unlikely to use it, but it's been proven |
796
|
|
|
|
|
|
|
useful for tools that integrate Type::Params with Moose-like method modifiers. |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
=head4 C<< strictness >> B<< Bool|Str >> |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
If you set C<strictness> to a false value (0, undef, or the empty string), |
801
|
|
|
|
|
|
|
then certain signature checks will simply never be done. The initial check |
802
|
|
|
|
|
|
|
that there's the correct number of parameters, plus type checks on parameters |
803
|
|
|
|
|
|
|
which don't coerce can be skipped. |
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
If you set it to a true boolean (i.e. 1) or do not set it at all, then these |
806
|
|
|
|
|
|
|
checks will always be done. |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
Alternatively, it may be set to the quoted fully-qualified name of a Perl |
809
|
|
|
|
|
|
|
global variable or a constant, and that will be compiled into the coderef |
810
|
|
|
|
|
|
|
as a condition to enable strict checks. |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
state $signature = signature( |
813
|
|
|
|
|
|
|
strictness => '$::CHECK_TYPES', |
814
|
|
|
|
|
|
|
positional => [ Int, ArrayRef ], |
815
|
|
|
|
|
|
|
); |
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
# Type checks are skipped |
818
|
|
|
|
|
|
|
{ |
819
|
|
|
|
|
|
|
local $::CHECK_TYPES = 0; |
820
|
|
|
|
|
|
|
my ( $number, $list ) = $signature->( {}, {} ); |
821
|
|
|
|
|
|
|
} |
822
|
|
|
|
|
|
|
|
823
|
|
|
|
|
|
|
# Type checks are performed |
824
|
|
|
|
|
|
|
{ |
825
|
|
|
|
|
|
|
local $::CHECK_TYPES = 1; |
826
|
|
|
|
|
|
|
my ( $number, $list ) = $signature->( {}, {} ); |
827
|
|
|
|
|
|
|
} |
828
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
A recommended use of this is with L<Devel::StrictMode>. |
830
|
|
|
|
|
|
|
|
831
|
|
|
|
|
|
|
use Devel::StrictMode qw( STRICT ); |
832
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
state $signature = signature( |
834
|
|
|
|
|
|
|
strictness => STRICT, |
835
|
|
|
|
|
|
|
positional => [ Int, ArrayRef ], |
836
|
|
|
|
|
|
|
); |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
=head4 C<< multiple >> B<< ArrayRef >> |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
This option allows your signature to support multiple calling conventions. |
841
|
|
|
|
|
|
|
Each entry in the array is an alternative signature, as a hashref: |
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
state $signature = signature( |
844
|
|
|
|
|
|
|
multiple => [ |
845
|
|
|
|
|
|
|
{ |
846
|
|
|
|
|
|
|
positional => [ ArrayRef, Int ], |
847
|
|
|
|
|
|
|
}, |
848
|
|
|
|
|
|
|
{ |
849
|
|
|
|
|
|
|
named => [ array => ArrayRef, index => Int ], |
850
|
|
|
|
|
|
|
named_to_list => 1, |
851
|
|
|
|
|
|
|
}, |
852
|
|
|
|
|
|
|
], |
853
|
|
|
|
|
|
|
); |
854
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
That signature will allow your function to be called as: |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
your_function( $arr, $ix ) |
858
|
|
|
|
|
|
|
your_function( array => $arr, index => $ix ) |
859
|
|
|
|
|
|
|
your_function( { array => $arr, index => $ix } ) |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
Sometimes the alternatives will return the parameters in a different |
862
|
|
|
|
|
|
|
order: |
863
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
state $signature = signature( |
865
|
|
|
|
|
|
|
multiple => [ |
866
|
|
|
|
|
|
|
{ positional => [ ArrayRef, Int ] }, |
867
|
|
|
|
|
|
|
{ positional => [ Int, ArrayRef ] }, |
868
|
|
|
|
|
|
|
], |
869
|
|
|
|
|
|
|
); |
870
|
|
|
|
|
|
|
my ( $xxx, $yyy ) = $signature->( @_ ); |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
So how does your sub know whether C<< $xxx >> or C<< $yyy >> is the arrayref? |
873
|
|
|
|
|
|
|
One option is to use the C<< ${^_TYPE_PARAMS_MULTISIG} >> global variable |
874
|
|
|
|
|
|
|
which will be set to the index of the signature which was used: |
875
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
my @results = $signature->( @_ ); |
877
|
|
|
|
|
|
|
my ( $arr, $ix ) = ${^_TYPE_PARAMS_MULTISIG} == 1 |
878
|
|
|
|
|
|
|
? reverse( @results ) |
879
|
|
|
|
|
|
|
: @results; |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
A neater solution is to use a C<goto_next> coderef to re-order alternative |
882
|
|
|
|
|
|
|
signature results into your preferred order: |
883
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
state $signature = signature( |
885
|
|
|
|
|
|
|
multiple => [ |
886
|
|
|
|
|
|
|
{ positional => [ ArrayRef, Int ] }, |
887
|
|
|
|
|
|
|
{ positional => [ Int, ArrayRef ], goto_next => sub { reverse @_ } }, |
888
|
|
|
|
|
|
|
], |
889
|
|
|
|
|
|
|
); |
890
|
|
|
|
|
|
|
my ( $arr, $ix ) = $signature->( @_ ); |
891
|
|
|
|
|
|
|
|
892
|
|
|
|
|
|
|
While conceptally C<multiple> is an arrayref of hashrefs, it is also possible |
893
|
|
|
|
|
|
|
to use arrayrefs in the arrayref. |
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
multiple => [ |
896
|
|
|
|
|
|
|
[ ArrayRef, Int ], |
897
|
|
|
|
|
|
|
[ Int, ArrayRef ], |
898
|
|
|
|
|
|
|
] |
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
When an arrayref is used like that, it is a shortcut for a positional |
901
|
|
|
|
|
|
|
signature. |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
Coderefs may additionally be used: |
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
state $signature = signature( |
906
|
|
|
|
|
|
|
multiple => [ |
907
|
|
|
|
|
|
|
[ ArrayRef, Int ], |
908
|
|
|
|
|
|
|
{ positional => [ Int, ArrayRef ], goto_next => sub { reverse @_ } }, |
909
|
|
|
|
|
|
|
sub { ... }, |
910
|
|
|
|
|
|
|
sub { ... }, |
911
|
|
|
|
|
|
|
], |
912
|
|
|
|
|
|
|
); |
913
|
|
|
|
|
|
|
|
914
|
|
|
|
|
|
|
The coderefs should be subs which return a list of parameters if they |
915
|
|
|
|
|
|
|
succeed and throw an exception if they fail. |
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
The following signatures are equivalent: |
918
|
|
|
|
|
|
|
|
919
|
|
|
|
|
|
|
state $sig_1 = signature( |
920
|
|
|
|
|
|
|
multiple => [ |
921
|
|
|
|
|
|
|
{ method => 1, positional => [ ArrayRef, Int ] }, |
922
|
|
|
|
|
|
|
{ method => 1, positional => [ Int, ArrayRef ] }, |
923
|
|
|
|
|
|
|
], |
924
|
|
|
|
|
|
|
); |
925
|
|
|
|
|
|
|
|
926
|
|
|
|
|
|
|
state $sig_2 = signature( |
927
|
|
|
|
|
|
|
method => 1, |
928
|
|
|
|
|
|
|
multiple => [ |
929
|
|
|
|
|
|
|
{ positional => [ ArrayRef, Int ] }, |
930
|
|
|
|
|
|
|
{ positional => [ Int, ArrayRef ] }, |
931
|
|
|
|
|
|
|
], |
932
|
|
|
|
|
|
|
); |
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
The C<multiple> option can also be abbreviated to C<multi>. |
935
|
|
|
|
|
|
|
|
936
|
|
|
|
|
|
|
So C<< signature( multi => [...] ) >> can be used instead of the longer |
937
|
|
|
|
|
|
|
C<< signature( multiple => [...] ) >>. Three whole keystrokes saved! |
938
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
(B<Note:> in older releases of Type::Params, C<< ${^_TYPE_PARAMS_MULTISIG} >> |
940
|
|
|
|
|
|
|
was called C<< ${^TYPE_PARAMS_MULTISIG} >>. The latter name is deprecated, |
941
|
|
|
|
|
|
|
and support for it will be removed in a future release of Type::Params.) |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
=head4 C<< message >> B<Str> |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
Only used by C<multiple> signatures. The error message to throw when no |
946
|
|
|
|
|
|
|
signatures match. |
947
|
|
|
|
|
|
|
|
948
|
|
|
|
|
|
|
=head4 C<< want_source >> B<Bool> |
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
Instead of returning a coderef, return Perl source code string. Handy |
951
|
|
|
|
|
|
|
for debugging. |
952
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
=head4 C<< want_details >> B<Bool> |
954
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
Instead of returning a coderef, return a hashref of stuff including the |
956
|
|
|
|
|
|
|
coderef. This is mostly for people extending Type::Params and I won't go |
957
|
|
|
|
|
|
|
into too many details about what else this hashref contains. |
958
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
=head4 C<< bless >> B<Bool|ClassName>, C<< class >> B<< ClassName|ArrayRef >>, and C<< constructor >> B<Str> |
960
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
Named parameters are usually returned as a blessed object: |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
sub add_numbers { |
964
|
|
|
|
|
|
|
state $sig = signature( named => [ num1 => Num, num2 => Num ] ); |
965
|
|
|
|
|
|
|
my ( $arg ) = $sig->( @_ ); |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
return $arg->num1 + $arg->num2; |
968
|
|
|
|
|
|
|
} |
969
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
The class they are blessed into is one built on-the-fly by Type::Params. |
971
|
|
|
|
|
|
|
However, these three signature options allow you more control over that |
972
|
|
|
|
|
|
|
process. |
973
|
|
|
|
|
|
|
|
974
|
|
|
|
|
|
|
Firstly, if you set C<< bless => false >> and do not set C<class> or |
975
|
|
|
|
|
|
|
C<constructor>, then C<< $arg >> will just be an unblessed hashref. |
976
|
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
sub add_numbers { |
978
|
|
|
|
|
|
|
state $sig = signature( |
979
|
|
|
|
|
|
|
named => [ num1 => Num, num2 => Num ], |
980
|
|
|
|
|
|
|
bless => !!0, |
981
|
|
|
|
|
|
|
); |
982
|
|
|
|
|
|
|
my ( $arg ) = $sig->( @_ ); |
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
return $arg->{num1} + $arg->{num2}; |
985
|
|
|
|
|
|
|
} |
986
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
This is a good speed boost, but having proper methods for each named |
988
|
|
|
|
|
|
|
parameter is a helpful way to catch misspelled names. |
989
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
If you wish to manually create a class instead of relying on Type::Params |
991
|
|
|
|
|
|
|
generating one on-the-fly, you can do this: |
992
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
package Params::For::AddNumbers { |
994
|
|
|
|
|
|
|
sub num1 { return $_[0]{num1} } |
995
|
|
|
|
|
|
|
sub num2 { return $_[0]{num2} } |
996
|
|
|
|
|
|
|
sub sum { |
997
|
|
|
|
|
|
|
my $self = shift; |
998
|
|
|
|
|
|
|
return $self->num1 + $self->num2; |
999
|
|
|
|
|
|
|
} |
1000
|
|
|
|
|
|
|
} |
1001
|
|
|
|
|
|
|
|
1002
|
|
|
|
|
|
|
sub add_numbers { |
1003
|
|
|
|
|
|
|
state $sig = signature( |
1004
|
|
|
|
|
|
|
named => [ num1 => Num, num2 => Num ], |
1005
|
|
|
|
|
|
|
bless => 'Params::For::AddNumbers', |
1006
|
|
|
|
|
|
|
); |
1007
|
|
|
|
|
|
|
my ( $arg ) = $sig->( @_ ); |
1008
|
|
|
|
|
|
|
|
1009
|
|
|
|
|
|
|
return $arg->sum; |
1010
|
|
|
|
|
|
|
} |
1011
|
|
|
|
|
|
|
|
1012
|
|
|
|
|
|
|
Note that C<Params::For::AddNumbers> here doesn't include a C<new> method |
1013
|
|
|
|
|
|
|
because Type::Params will directly do C<< bless( $arg, $opts{bless} ) >>. |
1014
|
|
|
|
|
|
|
|
1015
|
|
|
|
|
|
|
If you want Type::Params to use a proper constructor, you should use the |
1016
|
|
|
|
|
|
|
C<class> option instead: |
1017
|
|
|
|
|
|
|
|
1018
|
|
|
|
|
|
|
package Params::For::AddNumbers { |
1019
|
|
|
|
|
|
|
use Moo; |
1020
|
|
|
|
|
|
|
has [ 'num1', 'num2' ] => ( is => 'ro' ); |
1021
|
|
|
|
|
|
|
sub sum { |
1022
|
|
|
|
|
|
|
my $self = shift; |
1023
|
|
|
|
|
|
|
return $self->num1 + $self->num2; |
1024
|
|
|
|
|
|
|
} |
1025
|
|
|
|
|
|
|
} |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
sub add_numbers { |
1028
|
|
|
|
|
|
|
state $sig = signature( |
1029
|
|
|
|
|
|
|
named => [ num1 => Num, num2 => Num ], |
1030
|
|
|
|
|
|
|
class => 'Params::For::AddNumbers', |
1031
|
|
|
|
|
|
|
); |
1032
|
|
|
|
|
|
|
my ( $arg ) = $sig->( @_ ); |
1033
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
return $arg->sum; |
1035
|
|
|
|
|
|
|
} |
1036
|
|
|
|
|
|
|
|
1037
|
|
|
|
|
|
|
If you wish to use a constructor named something other than C<new>, then |
1038
|
|
|
|
|
|
|
use: |
1039
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
state $sig = signature( |
1041
|
|
|
|
|
|
|
named => [ num1 => Num, num2 => Num ], |
1042
|
|
|
|
|
|
|
class => 'Params::For::AddNumbers', |
1043
|
|
|
|
|
|
|
constructor => 'new_from_hashref', |
1044
|
|
|
|
|
|
|
); |
1045
|
|
|
|
|
|
|
|
1046
|
|
|
|
|
|
|
Or as a shortcut: |
1047
|
|
|
|
|
|
|
|
1048
|
|
|
|
|
|
|
state $sig = signature( |
1049
|
|
|
|
|
|
|
named => [ num1 => Num, num2 => Num ], |
1050
|
|
|
|
|
|
|
class => [ 'Params::For::AddNumbers', 'new_from_hashref' ], |
1051
|
|
|
|
|
|
|
); |
1052
|
|
|
|
|
|
|
|
1053
|
|
|
|
|
|
|
It is doubtful you want to use any of these options, except |
1054
|
|
|
|
|
|
|
C<< bless => false >>. |
1055
|
|
|
|
|
|
|
|
1056
|
|
|
|
|
|
|
=head3 Parameter Options |
1057
|
|
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
In the parameter lists for the C<positional> and C<named> signature |
1059
|
|
|
|
|
|
|
options, each parameter may be followed by a hashref of options specific |
1060
|
|
|
|
|
|
|
to that parameter: |
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
signature( |
1063
|
|
|
|
|
|
|
positional => [ |
1064
|
|
|
|
|
|
|
Int, \%options_for_first_parameter, |
1065
|
|
|
|
|
|
|
Int, \%options_for_other_parameter, |
1066
|
|
|
|
|
|
|
], |
1067
|
|
|
|
|
|
|
%more_options_for_signature, |
1068
|
|
|
|
|
|
|
); |
1069
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
signature( |
1071
|
|
|
|
|
|
|
named => [ |
1072
|
|
|
|
|
|
|
foo => Int, \%options_for_foo, |
1073
|
|
|
|
|
|
|
bar => Int, \%options_for_bar, |
1074
|
|
|
|
|
|
|
], |
1075
|
|
|
|
|
|
|
%more_options_for_signature, |
1076
|
|
|
|
|
|
|
); |
1077
|
|
|
|
|
|
|
|
1078
|
|
|
|
|
|
|
The following options are supported for parameters. |
1079
|
|
|
|
|
|
|
|
1080
|
|
|
|
|
|
|
=head4 C<< optional >> B<Bool> |
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
An option I<called> optional! |
1083
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
This makes a parameter optional: |
1085
|
|
|
|
|
|
|
|
1086
|
|
|
|
|
|
|
sub add_nums { |
1087
|
|
|
|
|
|
|
state $sig = signature( |
1088
|
|
|
|
|
|
|
positional => [ |
1089
|
|
|
|
|
|
|
Int, |
1090
|
|
|
|
|
|
|
Int, |
1091
|
|
|
|
|
|
|
Bool, { optional => !!1 }, |
1092
|
|
|
|
|
|
|
], |
1093
|
|
|
|
|
|
|
); |
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
my ( $num1, $num2, $debug ) = $sig->( @_ ); |
1096
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
my $sum = $num1 + $num2; |
1098
|
|
|
|
|
|
|
warn "$sum = $num1 + $num2" if $debug; |
1099
|
|
|
|
|
|
|
|
1100
|
|
|
|
|
|
|
return $sum; |
1101
|
|
|
|
|
|
|
} |
1102
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
add_nums( 2, 3, 1 ); # prints warning |
1104
|
|
|
|
|
|
|
add_nums( 2, 3, 0 ); # no warning |
1105
|
|
|
|
|
|
|
add_nums( 2, 3 ); # no warning |
1106
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
L<Types::Standard> also provides a B<Optional> parameterizable type |
1108
|
|
|
|
|
|
|
which may be a neater way to do this: |
1109
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
state $sig = signature( |
1111
|
|
|
|
|
|
|
positional => [ Int, Int, Optional[Bool] ], |
1112
|
|
|
|
|
|
|
); |
1113
|
|
|
|
|
|
|
|
1114
|
|
|
|
|
|
|
In signatures with positional parameters, any optional parameters must be |
1115
|
|
|
|
|
|
|
defined I<after> non-optional parameters. The C<tail> option provides a |
1116
|
|
|
|
|
|
|
workaround for required parameters at the end of C<< @_ >>. |
1117
|
|
|
|
|
|
|
|
1118
|
|
|
|
|
|
|
In signatures with named parameters, the order of optional and non-optional |
1119
|
|
|
|
|
|
|
parameters is unimportant. |
1120
|
|
|
|
|
|
|
|
1121
|
|
|
|
|
|
|
=head4 C<< slurpy >> B<Bool> |
1122
|
|
|
|
|
|
|
|
1123
|
|
|
|
|
|
|
A signature may contain a single slurpy parameter, which mops up any other |
1124
|
|
|
|
|
|
|
arguments the caller provides your function. |
1125
|
|
|
|
|
|
|
|
1126
|
|
|
|
|
|
|
In signatures with positional parameters, slurpy params must always have |
1127
|
|
|
|
|
|
|
some kind of B<ArrayRef> or B<HashRef> type constraint, must always appear |
1128
|
|
|
|
|
|
|
at the I<end> of the list of positional parameters, and they work like this: |
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
sub add_nums { |
1131
|
|
|
|
|
|
|
state $sig = signature( |
1132
|
|
|
|
|
|
|
positional => [ |
1133
|
|
|
|
|
|
|
Num, |
1134
|
|
|
|
|
|
|
ArrayRef[Num], { slurpy => !!1 }, |
1135
|
|
|
|
|
|
|
], |
1136
|
|
|
|
|
|
|
); |
1137
|
|
|
|
|
|
|
my ( $first_num, $other_nums ) = $sig->( @_ ); |
1138
|
|
|
|
|
|
|
|
1139
|
|
|
|
|
|
|
my $sum = $first_num; |
1140
|
|
|
|
|
|
|
$sum += $_ for @$other_nums; |
1141
|
|
|
|
|
|
|
|
1142
|
|
|
|
|
|
|
return $sum; |
1143
|
|
|
|
|
|
|
} |
1144
|
|
|
|
|
|
|
|
1145
|
|
|
|
|
|
|
say add_nums( 1 ); # says 1 |
1146
|
|
|
|
|
|
|
say add_nums( 1, 2 ); # says 3 |
1147
|
|
|
|
|
|
|
say add_nums( 1, 2, 3 ); # says 6 |
1148
|
|
|
|
|
|
|
say add_nums( 1, 2, 3, 4 ); # says 10 |
1149
|
|
|
|
|
|
|
|
1150
|
|
|
|
|
|
|
In signatures with named parameters, slurpy params must always have |
1151
|
|
|
|
|
|
|
some kind of B<HashRef> type constraint, and they work like this: |
1152
|
|
|
|
|
|
|
|
1153
|
|
|
|
|
|
|
use builtin qw( true false ); |
1154
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
sub process_data { |
1156
|
|
|
|
|
|
|
state $sig = signature( |
1157
|
|
|
|
|
|
|
method => true, |
1158
|
|
|
|
|
|
|
named => [ |
1159
|
|
|
|
|
|
|
input => FileHandle, |
1160
|
|
|
|
|
|
|
output => FileHandle, |
1161
|
|
|
|
|
|
|
flags => HashRef[Bool], { slurpy => true }, |
1162
|
|
|
|
|
|
|
], |
1163
|
|
|
|
|
|
|
); |
1164
|
|
|
|
|
|
|
my ( $self, $arg ) = @_; |
1165
|
|
|
|
|
|
|
warn "Beginning data processing" if $arg->flags->{debug}; |
1166
|
|
|
|
|
|
|
|
1167
|
|
|
|
|
|
|
...; |
1168
|
|
|
|
|
|
|
} |
1169
|
|
|
|
|
|
|
|
1170
|
|
|
|
|
|
|
$widget->process_data( |
1171
|
|
|
|
|
|
|
input => \*STDIN, |
1172
|
|
|
|
|
|
|
output => \*STDOUT, |
1173
|
|
|
|
|
|
|
debug => true, |
1174
|
|
|
|
|
|
|
); |
1175
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
The B<Slurpy> type constraint from L<Types::Standard> may be used as |
1177
|
|
|
|
|
|
|
a shortcut to specify slurpy parameters: |
1178
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
signature( |
1180
|
|
|
|
|
|
|
positional => [ Num, Slurpy[ ArrayRef[Num] ] ], |
1181
|
|
|
|
|
|
|
) |
1182
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
The type B<< Slurpy[Any] >> is handled specially and treated as a |
1184
|
|
|
|
|
|
|
slurpy B<ArrayRef> in signatures with positional parameters, and a |
1185
|
|
|
|
|
|
|
slurpy B<HashRef> in signatures with named parameters, but has some |
1186
|
|
|
|
|
|
|
additional optimizations for speed. |
1187
|
|
|
|
|
|
|
|
1188
|
|
|
|
|
|
|
=head4 C<< default >> B<< CodeRef|ScalarRef|Ref|Str|Undef >> |
1189
|
|
|
|
|
|
|
|
1190
|
|
|
|
|
|
|
A default may be provided for a parameter. |
1191
|
|
|
|
|
|
|
|
1192
|
|
|
|
|
|
|
state $check = signature( |
1193
|
|
|
|
|
|
|
positional => [ |
1194
|
|
|
|
|
|
|
Int, |
1195
|
|
|
|
|
|
|
Int, { default => "666" }, |
1196
|
|
|
|
|
|
|
Int, { default => "999" }, |
1197
|
|
|
|
|
|
|
], |
1198
|
|
|
|
|
|
|
); |
1199
|
|
|
|
|
|
|
|
1200
|
|
|
|
|
|
|
Supported defaults are any strings (including numerical ones), C<undef>, |
1201
|
|
|
|
|
|
|
and empty hashrefs and arrayrefs. Non-empty hashrefs and arrayrefs are |
1202
|
|
|
|
|
|
|
I<< not allowed as defaults >>. |
1203
|
|
|
|
|
|
|
|
1204
|
|
|
|
|
|
|
Alternatively, you may provide a coderef to generate a default value: |
1205
|
|
|
|
|
|
|
|
1206
|
|
|
|
|
|
|
state $check = signature( |
1207
|
|
|
|
|
|
|
positional => [ |
1208
|
|
|
|
|
|
|
Int, |
1209
|
|
|
|
|
|
|
Int, { default => sub { 6 * 111 } }, |
1210
|
|
|
|
|
|
|
Int, { default => sub { 9 * 111 } }, |
1211
|
|
|
|
|
|
|
] |
1212
|
|
|
|
|
|
|
); |
1213
|
|
|
|
|
|
|
|
1214
|
|
|
|
|
|
|
That coderef may generate any value, including non-empty arrayrefs and |
1215
|
|
|
|
|
|
|
non-empty hashrefs. For undef, simple strings, numbers, and empty |
1216
|
|
|
|
|
|
|
structures, avoiding using a coderef will make your parameter processing |
1217
|
|
|
|
|
|
|
faster. |
1218
|
|
|
|
|
|
|
|
1219
|
|
|
|
|
|
|
Instead of a coderef, you can use a reference to a string of Perl source |
1220
|
|
|
|
|
|
|
code: |
1221
|
|
|
|
|
|
|
|
1222
|
|
|
|
|
|
|
state $check = signature( |
1223
|
|
|
|
|
|
|
positional => [ |
1224
|
|
|
|
|
|
|
Int, |
1225
|
|
|
|
|
|
|
Int, { default => \ '6 * 111' }, |
1226
|
|
|
|
|
|
|
Int, { default => \ '9 * 111' }, |
1227
|
|
|
|
|
|
|
], |
1228
|
|
|
|
|
|
|
); |
1229
|
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
Defaults I<will> be validated against the type constraint, and |
1231
|
|
|
|
|
|
|
potentially coerced. |
1232
|
|
|
|
|
|
|
|
1233
|
|
|
|
|
|
|
Any parameter with a default will automatically be optional. |
1234
|
|
|
|
|
|
|
|
1235
|
|
|
|
|
|
|
Note that having I<any> defaults in a signature (even if they never |
1236
|
|
|
|
|
|
|
end up getting used) can slow it down, as Type::Params will need to |
1237
|
|
|
|
|
|
|
build a new array instead of just returning C<< @_ >>. |
1238
|
|
|
|
|
|
|
|
1239
|
|
|
|
|
|
|
=head4 C<< coerce >> B<Bool> |
1240
|
|
|
|
|
|
|
|
1241
|
|
|
|
|
|
|
Speaking of which, the C<coerce> option allows you to indicate that a |
1242
|
|
|
|
|
|
|
value should be coerced into the correct type: |
1243
|
|
|
|
|
|
|
|
1244
|
|
|
|
|
|
|
state $sig = signature( |
1245
|
|
|
|
|
|
|
positional => [ |
1246
|
|
|
|
|
|
|
Int, |
1247
|
|
|
|
|
|
|
Int, |
1248
|
|
|
|
|
|
|
Bool, { coerce => true }, |
1249
|
|
|
|
|
|
|
], |
1250
|
|
|
|
|
|
|
); |
1251
|
|
|
|
|
|
|
|
1252
|
|
|
|
|
|
|
Setting C<coerce> to false will disable coercion. |
1253
|
|
|
|
|
|
|
|
1254
|
|
|
|
|
|
|
If C<coerce> is not specified, so is neither true nor false, then |
1255
|
|
|
|
|
|
|
coercion will be enabled if the type constraint has a coercion, and |
1256
|
|
|
|
|
|
|
disabled otherwise. |
1257
|
|
|
|
|
|
|
|
1258
|
|
|
|
|
|
|
Note that having I<any> coercions in a signature (even if they never |
1259
|
|
|
|
|
|
|
end up getting used) can slow it down, as Type::Params will need to |
1260
|
|
|
|
|
|
|
build a new array instead of just returning C<< @_ >>. |
1261
|
|
|
|
|
|
|
|
1262
|
|
|
|
|
|
|
=head4 C<< clone >> B<Bool> |
1263
|
|
|
|
|
|
|
|
1264
|
|
|
|
|
|
|
If this is set to true, it will deep clone incoming values via C<dclone> |
1265
|
|
|
|
|
|
|
from L<Storable> (a core module since Perl 5.7.3). |
1266
|
|
|
|
|
|
|
|
1267
|
|
|
|
|
|
|
In the below example, C<< $arr >> is a reference to a I<clone of> |
1268
|
|
|
|
|
|
|
C<< @numbers >>, so pushing additional numbers to it leaves C<< @numbers >> |
1269
|
|
|
|
|
|
|
unaffected. |
1270
|
|
|
|
|
|
|
|
1271
|
|
|
|
|
|
|
sub foo { |
1272
|
|
|
|
|
|
|
state $check = signature( |
1273
|
|
|
|
|
|
|
positional => [ |
1274
|
|
|
|
|
|
|
ArrayRef, { clone => 1 } |
1275
|
|
|
|
|
|
|
], |
1276
|
|
|
|
|
|
|
); |
1277
|
|
|
|
|
|
|
my ( $arr ) = &$check; |
1278
|
|
|
|
|
|
|
|
1279
|
|
|
|
|
|
|
push @$arr, 4, 5, 6; |
1280
|
|
|
|
|
|
|
} |
1281
|
|
|
|
|
|
|
|
1282
|
|
|
|
|
|
|
my @numbers = ( 1, 2, 3 ); |
1283
|
|
|
|
|
|
|
foo( \@numbers ); |
1284
|
|
|
|
|
|
|
|
1285
|
|
|
|
|
|
|
print "@numbers\n"; ## 1 2 3 |
1286
|
|
|
|
|
|
|
|
1287
|
|
|
|
|
|
|
Note that cloning will significantly slow down your signature. |
1288
|
|
|
|
|
|
|
|
1289
|
|
|
|
|
|
|
=head4 C<< name >> B<Str> |
1290
|
|
|
|
|
|
|
|
1291
|
|
|
|
|
|
|
This overrides the name of a named parameter. I don't know why you |
1292
|
|
|
|
|
|
|
would want to do that. |
1293
|
|
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
The following signature has two parameters: C<foo> and C<bar>. The |
1295
|
|
|
|
|
|
|
name C<fool> is completely ignored. |
1296
|
|
|
|
|
|
|
|
1297
|
|
|
|
|
|
|
signature( |
1298
|
|
|
|
|
|
|
named => [ |
1299
|
|
|
|
|
|
|
fool => Int, { name => 'foo' }, |
1300
|
|
|
|
|
|
|
bar => Int, |
1301
|
|
|
|
|
|
|
], |
1302
|
|
|
|
|
|
|
) |
1303
|
|
|
|
|
|
|
|
1304
|
|
|
|
|
|
|
You can, however, also name positional parameters, which don't usually |
1305
|
|
|
|
|
|
|
have names. |
1306
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
signature( |
1308
|
|
|
|
|
|
|
positional => [ |
1309
|
|
|
|
|
|
|
Int, { name => 'foo' }, |
1310
|
|
|
|
|
|
|
Int, { name => 'bar' }, |
1311
|
|
|
|
|
|
|
], |
1312
|
|
|
|
|
|
|
) |
1313
|
|
|
|
|
|
|
|
1314
|
|
|
|
|
|
|
The names of positional parameters are not really I<used> for anything |
1315
|
|
|
|
|
|
|
at the moment, but may be incorporated into error messages or |
1316
|
|
|
|
|
|
|
similar in the future. |
1317
|
|
|
|
|
|
|
|
1318
|
|
|
|
|
|
|
=head4 C<< getter >> B<Str> |
1319
|
|
|
|
|
|
|
|
1320
|
|
|
|
|
|
|
For signatures with named parameters, specifies the method name used |
1321
|
|
|
|
|
|
|
to retrieve this parameter's value from the C<< $arg >> object. |
1322
|
|
|
|
|
|
|
|
1323
|
|
|
|
|
|
|
sub process_data { |
1324
|
|
|
|
|
|
|
state $sig = signature( |
1325
|
|
|
|
|
|
|
method => true, |
1326
|
|
|
|
|
|
|
named => [ |
1327
|
|
|
|
|
|
|
input => FileHandle, { getter => 'in' }, |
1328
|
|
|
|
|
|
|
output => FileHandle, { getter => 'out' }, |
1329
|
|
|
|
|
|
|
flags => HashRef[Bool], { slurpy => true }, |
1330
|
|
|
|
|
|
|
], |
1331
|
|
|
|
|
|
|
); |
1332
|
|
|
|
|
|
|
my ( $self, $arg ) = @_; |
1333
|
|
|
|
|
|
|
warn "Beginning data processing" if $arg->flags->{debug}; |
1334
|
|
|
|
|
|
|
|
1335
|
|
|
|
|
|
|
my ( $in, $out ) = ( $arg->in, $arg->out ); |
1336
|
|
|
|
|
|
|
...; |
1337
|
|
|
|
|
|
|
} |
1338
|
|
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
$widget->process_data( |
1340
|
|
|
|
|
|
|
input => \*STDIN, |
1341
|
|
|
|
|
|
|
output => \*STDOUT, |
1342
|
|
|
|
|
|
|
debug => true, |
1343
|
|
|
|
|
|
|
); |
1344
|
|
|
|
|
|
|
|
1345
|
|
|
|
|
|
|
Ignored by signatures with positional parameters. |
1346
|
|
|
|
|
|
|
|
1347
|
|
|
|
|
|
|
=head4 C<< predicate >> B<Str> |
1348
|
|
|
|
|
|
|
|
1349
|
|
|
|
|
|
|
The C<< $arg >> object provided by signatures with named parameters |
1350
|
|
|
|
|
|
|
will also include "has" methods for any optional arguments. |
1351
|
|
|
|
|
|
|
For example: |
1352
|
|
|
|
|
|
|
|
1353
|
|
|
|
|
|
|
state $sig = signature( |
1354
|
|
|
|
|
|
|
method => true, |
1355
|
|
|
|
|
|
|
named => [ |
1356
|
|
|
|
|
|
|
input => Optional[ FileHandle ], |
1357
|
|
|
|
|
|
|
output => Optional[ FileHandle ], |
1358
|
|
|
|
|
|
|
flags => Slurpy[ HashRef[Bool] ], |
1359
|
|
|
|
|
|
|
], |
1360
|
|
|
|
|
|
|
); |
1361
|
|
|
|
|
|
|
my ( $self, $arg ) = $sig->( @_ ); |
1362
|
|
|
|
|
|
|
|
1363
|
|
|
|
|
|
|
if ( $self->has_input and $self->has_output ) { |
1364
|
|
|
|
|
|
|
...; |
1365
|
|
|
|
|
|
|
} |
1366
|
|
|
|
|
|
|
|
1367
|
|
|
|
|
|
|
Setting a C<predicate> option allows you to choose a different name |
1368
|
|
|
|
|
|
|
for this method. |
1369
|
|
|
|
|
|
|
|
1370
|
|
|
|
|
|
|
It is also possible to set a C<predicate> for non-optional parameters, |
1371
|
|
|
|
|
|
|
which don't normally get a "has" method. |
1372
|
|
|
|
|
|
|
|
1373
|
|
|
|
|
|
|
Ignored by signatures with positional parameters. |
1374
|
|
|
|
|
|
|
|
1375
|
|
|
|
|
|
|
=head4 C<< alias >> B<< Str|ArrayRef[Str] >> |
1376
|
|
|
|
|
|
|
|
1377
|
|
|
|
|
|
|
A list of alternative names for the parameter, or a single alternative |
1378
|
|
|
|
|
|
|
name. |
1379
|
|
|
|
|
|
|
|
1380
|
|
|
|
|
|
|
sub add_numbers { |
1381
|
|
|
|
|
|
|
state $sig = signature( |
1382
|
|
|
|
|
|
|
named => [ |
1383
|
|
|
|
|
|
|
first_number => Int, { alias => [ 'x' ] }, |
1384
|
|
|
|
|
|
|
second_number => Int, { alias => 'y' }, |
1385
|
|
|
|
|
|
|
], |
1386
|
|
|
|
|
|
|
); |
1387
|
|
|
|
|
|
|
my ( $arg ) = $sig->( @_ ); |
1388
|
|
|
|
|
|
|
|
1389
|
|
|
|
|
|
|
return $arg->first_number + $arg->second_number; |
1390
|
|
|
|
|
|
|
} |
1391
|
|
|
|
|
|
|
|
1392
|
|
|
|
|
|
|
say add_numbers( first_number => 40, second_number => 2 ); # 42 |
1393
|
|
|
|
|
|
|
say add_numbers( x => 40, y => 2 ); # 42 |
1394
|
|
|
|
|
|
|
say add_numbers( first_number => 40, y => 2 ); # 42 |
1395
|
|
|
|
|
|
|
say add_numbers( first_number => 40, x => 1, y => 2 ); # dies! |
1396
|
|
|
|
|
|
|
|
1397
|
|
|
|
|
|
|
Ignored by signatures with positional parameters. |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
=head4 C<< strictness >> B<Bool|Str> |
1400
|
|
|
|
|
|
|
|
1401
|
|
|
|
|
|
|
Overrides the signature option C<strictness> on a per-parameter basis. |
1402
|
|
|
|
|
|
|
|
1403
|
|
|
|
|
|
|
=head2 C<< signature_for $function_name => ( %spec ) >> |
1404
|
|
|
|
|
|
|
|
1405
|
|
|
|
|
|
|
Like C<signature>, but instead of returning a coderef, wraps an existing |
1406
|
|
|
|
|
|
|
function, so you don't need to deal with the mechanics of generating the |
1407
|
|
|
|
|
|
|
signature at run-time, calling it, and extracting the returned values. |
1408
|
|
|
|
|
|
|
|
1409
|
|
|
|
|
|
|
The following three examples are roughly equivalent: |
1410
|
|
|
|
|
|
|
|
1411
|
|
|
|
|
|
|
sub add_nums { |
1412
|
|
|
|
|
|
|
state $signature = signature( |
1413
|
|
|
|
|
|
|
positional => [ Num, Num ], |
1414
|
|
|
|
|
|
|
); |
1415
|
|
|
|
|
|
|
my ( $x, $y ) = $signature->( @_ ); |
1416
|
|
|
|
|
|
|
|
1417
|
|
|
|
|
|
|
return $x + $y; |
1418
|
|
|
|
|
|
|
} |
1419
|
|
|
|
|
|
|
|
1420
|
|
|
|
|
|
|
Or: |
1421
|
|
|
|
|
|
|
|
1422
|
|
|
|
|
|
|
signature_for add_nums => ( |
1423
|
|
|
|
|
|
|
positional => [ Num, Num ], |
1424
|
|
|
|
|
|
|
); |
1425
|
|
|
|
|
|
|
|
1426
|
|
|
|
|
|
|
sub add_nums { |
1427
|
|
|
|
|
|
|
my ( $x, $y ) = @_; |
1428
|
|
|
|
|
|
|
|
1429
|
|
|
|
|
|
|
return $x + $y; |
1430
|
|
|
|
|
|
|
} |
1431
|
|
|
|
|
|
|
|
1432
|
|
|
|
|
|
|
Or since Perl 5.20: |
1433
|
|
|
|
|
|
|
|
1434
|
|
|
|
|
|
|
signature_for add_nums => ( |
1435
|
|
|
|
|
|
|
positional => [ Num, Num ], |
1436
|
|
|
|
|
|
|
); |
1437
|
|
|
|
|
|
|
|
1438
|
|
|
|
|
|
|
sub add_nums ( $x, $y ) { |
1439
|
|
|
|
|
|
|
return $x + $y; |
1440
|
|
|
|
|
|
|
} |
1441
|
|
|
|
|
|
|
|
1442
|
|
|
|
|
|
|
The C<signature_for> keyword turns C<signature> inside-out. |
1443
|
|
|
|
|
|
|
|
1444
|
|
|
|
|
|
|
The same signature specification options are supported, with the exception |
1445
|
|
|
|
|
|
|
of C<want_source>, C<want_details>, and C<goto_next> which will not work. |
1446
|
|
|
|
|
|
|
(If using the C<multiple> option, then C<goto_next> is still supported in |
1447
|
|
|
|
|
|
|
the I<nested> signatures.) |
1448
|
|
|
|
|
|
|
|
1449
|
|
|
|
|
|
|
If you are providing a signature for a sub in another package, then |
1450
|
|
|
|
|
|
|
C<< signature_for "Some::Package::some_sub" => ( ... ) >> will work, |
1451
|
|
|
|
|
|
|
as will C<< signature_for some_sub => ( package => "Some::Package", ... ) >>. |
1452
|
|
|
|
|
|
|
If C<method> is true, then C<signature_for> will respect inheritance when |
1453
|
|
|
|
|
|
|
determining which sub to wrap. C<signature_for> will not be able to find |
1454
|
|
|
|
|
|
|
lexical subs, so use C<signature> within the sub instead. |
1455
|
|
|
|
|
|
|
|
1456
|
|
|
|
|
|
|
The C<goto_next> option is what C<signature_for> uses to "connect" the |
1457
|
|
|
|
|
|
|
signature to the body of the sub, so do not use it unless you understand |
1458
|
|
|
|
|
|
|
the consequences and want to override the normal behaviour. |
1459
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
If the sub being wrapped cannot be found, then C<signature_for> will usually |
1461
|
|
|
|
|
|
|
throw an error. If you want it to "work" in this situation, use the |
1462
|
|
|
|
|
|
|
C<fallback> option. C<< fallback => \&alternative_coderef_to_wrap >> |
1463
|
|
|
|
|
|
|
will instead wrap a different coderef if the original cannot be found. |
1464
|
|
|
|
|
|
|
C<< fallback => 1 >> is a shortcut for C<< fallback => sub {} >>. |
1465
|
|
|
|
|
|
|
An example where this might be useful is if you're adding signatures to |
1466
|
|
|
|
|
|
|
methods which are inherited from a parent class, but you are not 100% |
1467
|
|
|
|
|
|
|
confident will exist (perhaps dependent on the version of the parent class). |
1468
|
|
|
|
|
|
|
|
1469
|
|
|
|
|
|
|
signature_for add_nums => ( |
1470
|
|
|
|
|
|
|
positional => [ Num, Num ], |
1471
|
|
|
|
|
|
|
fallback => sub { $_[0] + $_[1] }, |
1472
|
|
|
|
|
|
|
); |
1473
|
|
|
|
|
|
|
|
1474
|
|
|
|
|
|
|
C<< signature_for( \@functions, %opts ) >> is a useful shortcut if you have |
1475
|
|
|
|
|
|
|
multiple functions with the same signature. |
1476
|
|
|
|
|
|
|
|
1477
|
|
|
|
|
|
|
signature_for [ 'add_nums', 'subtract_nums' ] => ( |
1478
|
|
|
|
|
|
|
positional => [ Num, Num ], |
1479
|
|
|
|
|
|
|
); |
1480
|
|
|
|
|
|
|
|
1481
|
|
|
|
|
|
|
=head1 LEGACY API |
1482
|
|
|
|
|
|
|
|
1483
|
|
|
|
|
|
|
The following functions were the API prior to Type::Params v2. They are |
1484
|
|
|
|
|
|
|
still supported, but their use is now discouraged. |
1485
|
|
|
|
|
|
|
|
1486
|
|
|
|
|
|
|
If you don't provide an import list at all, you will import C<compile> |
1487
|
|
|
|
|
|
|
and C<compile_named>: |
1488
|
|
|
|
|
|
|
|
1489
|
|
|
|
|
|
|
use Type::Params; |
1490
|
|
|
|
|
|
|
|
1491
|
|
|
|
|
|
|
This does the same: |
1492
|
|
|
|
|
|
|
|
1493
|
|
|
|
|
|
|
use Type::Params -v1; |
1494
|
|
|
|
|
|
|
|
1495
|
|
|
|
|
|
|
The following exports C<compile>, C<compile_named>, and C<compile_named_oo>: |
1496
|
|
|
|
|
|
|
|
1497
|
|
|
|
|
|
|
use Type::Params -compile; |
1498
|
|
|
|
|
|
|
|
1499
|
|
|
|
|
|
|
The following exports C<wrap_subs> and C<wrap_methods>: |
1500
|
|
|
|
|
|
|
|
1501
|
|
|
|
|
|
|
use Type::Params -wrap; |
1502
|
|
|
|
|
|
|
|
1503
|
|
|
|
|
|
|
=head2 C<< compile( @pos_params ) >> |
1504
|
|
|
|
|
|
|
|
1505
|
|
|
|
|
|
|
Equivalent to C<< signature( positional => \@pos_params ) >>. |
1506
|
|
|
|
|
|
|
|
1507
|
|
|
|
|
|
|
C<< compile( \%spec, @pos_params ) >> is equivalent to |
1508
|
|
|
|
|
|
|
C<< signature( %spec, positional => \@pos_params ) >>. |
1509
|
|
|
|
|
|
|
|
1510
|
|
|
|
|
|
|
=head2 C<< compile_named( @named_params ) >> |
1511
|
|
|
|
|
|
|
|
1512
|
|
|
|
|
|
|
Equivalent to C<< signature( bless => 0, named => \@named_params ) >>. |
1513
|
|
|
|
|
|
|
|
1514
|
|
|
|
|
|
|
C<< compile_named( \%spec, @named_params ) >> is equivalent to |
1515
|
|
|
|
|
|
|
C<< signature( bless => 0, %spec, named => \@named_params ) >>. |
1516
|
|
|
|
|
|
|
|
1517
|
|
|
|
|
|
|
=head2 C<< compile_named_oo( @named_params ) >> |
1518
|
|
|
|
|
|
|
|
1519
|
|
|
|
|
|
|
Equivalent to C<< signature( bless => 1, named => \@named_params ) >>. |
1520
|
|
|
|
|
|
|
|
1521
|
|
|
|
|
|
|
C<< compile_named_oo( \%spec, @named_params ) >> is equivalent to |
1522
|
|
|
|
|
|
|
C<< signature( bless => 1, %spec, named => \@named_params ) >>. |
1523
|
|
|
|
|
|
|
|
1524
|
|
|
|
|
|
|
=head2 C<< validate( \@args, @pos_params ) >> |
1525
|
|
|
|
|
|
|
|
1526
|
|
|
|
|
|
|
Equivalent to C<< signature( positional => \@pos_params )->( @args ) >>. |
1527
|
|
|
|
|
|
|
|
1528
|
|
|
|
|
|
|
The C<validate> function has I<never> been recommended, and is not |
1529
|
|
|
|
|
|
|
exported unless requested by name. |
1530
|
|
|
|
|
|
|
|
1531
|
|
|
|
|
|
|
=head2 C<< validate_named( \@args, @named_params ) >> |
1532
|
|
|
|
|
|
|
|
1533
|
|
|
|
|
|
|
Equivalent to C<< signature( bless => 0, named => \@named_params )->( @args ) >>. |
1534
|
|
|
|
|
|
|
|
1535
|
|
|
|
|
|
|
The C<validate_named> function has I<never> been recommended, and is not |
1536
|
|
|
|
|
|
|
exported unless requested by name. |
1537
|
|
|
|
|
|
|
|
1538
|
|
|
|
|
|
|
=head2 C<< wrap_subs( func1 => \@params1, func2 => \@params2, ... ) >> |
1539
|
|
|
|
|
|
|
|
1540
|
|
|
|
|
|
|
Equivalent to: |
1541
|
|
|
|
|
|
|
|
1542
|
|
|
|
|
|
|
signature_for func1 => ( positional => \@params1 ); |
1543
|
|
|
|
|
|
|
signature_for func2 => ( positional => \@params2 ); |
1544
|
|
|
|
|
|
|
|
1545
|
|
|
|
|
|
|
One slight difference is that instead of arrayrefs, you can provide the |
1546
|
|
|
|
|
|
|
output of one of the C<compile> functions: |
1547
|
|
|
|
|
|
|
|
1548
|
|
|
|
|
|
|
wrap_subs( func1 => compile_named( @params1 ) ); |
1549
|
|
|
|
|
|
|
|
1550
|
|
|
|
|
|
|
C<wrap_subs> is not exported unless requested by name. |
1551
|
|
|
|
|
|
|
|
1552
|
|
|
|
|
|
|
=head2 C<< wrap_methods( func1 => \@params1, func2 => \@params2, ... ) >> |
1553
|
|
|
|
|
|
|
|
1554
|
|
|
|
|
|
|
Equivalent to: |
1555
|
|
|
|
|
|
|
|
1556
|
|
|
|
|
|
|
signature_for func1 => ( method => 1, positional => \@params1 ); |
1557
|
|
|
|
|
|
|
signature_for func2 => ( method => 1, positional => \@params2 ); |
1558
|
|
|
|
|
|
|
|
1559
|
|
|
|
|
|
|
One slight difference is that instead of arrayrefs, you can provide the |
1560
|
|
|
|
|
|
|
output of one of the C<compile> functions: |
1561
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
wrap_methods( func1 => compile_named( @params1 ) ); |
1563
|
|
|
|
|
|
|
|
1564
|
|
|
|
|
|
|
C<wrap_methods> is not exported unless requested by name. |
1565
|
|
|
|
|
|
|
|
1566
|
|
|
|
|
|
|
=head2 C<< multisig( @alternatives ) >> |
1567
|
|
|
|
|
|
|
|
1568
|
|
|
|
|
|
|
Equivalent to: |
1569
|
|
|
|
|
|
|
|
1570
|
|
|
|
|
|
|
signature( multiple => \@alternatives ) |
1571
|
|
|
|
|
|
|
|
1572
|
|
|
|
|
|
|
C<< multisig( \%spec, @alternatives ) >> is equivalent to |
1573
|
|
|
|
|
|
|
C<< signature( %spec, multiple => \@alternatives ) >>. |
1574
|
|
|
|
|
|
|
|
1575
|
|
|
|
|
|
|
=head1 TYPE CONSTRAINTS |
1576
|
|
|
|
|
|
|
|
1577
|
|
|
|
|
|
|
Although Type::Params is not a real type library, it exports two type |
1578
|
|
|
|
|
|
|
constraints. Their use is no longer recommended. |
1579
|
|
|
|
|
|
|
|
1580
|
|
|
|
|
|
|
=head2 B<Invocant> |
1581
|
|
|
|
|
|
|
|
1582
|
|
|
|
|
|
|
Type::Params exports a type B<Invocant> on request. This gives you a type |
1583
|
|
|
|
|
|
|
constraint which accepts classnames I<and> blessed objects. |
1584
|
|
|
|
|
|
|
|
1585
|
|
|
|
|
|
|
use Type::Params qw( compile Invocant ); |
1586
|
|
|
|
|
|
|
|
1587
|
|
|
|
|
|
|
sub my_method { |
1588
|
|
|
|
|
|
|
state $check = signature( |
1589
|
|
|
|
|
|
|
method => Invocant, |
1590
|
|
|
|
|
|
|
positional => [ ArrayRef, Int ], |
1591
|
|
|
|
|
|
|
); |
1592
|
|
|
|
|
|
|
my ($self_or_class, $arr, $ix) = $check->(@_); |
1593
|
|
|
|
|
|
|
|
1594
|
|
|
|
|
|
|
return $arr->[ $ix ]; |
1595
|
|
|
|
|
|
|
} |
1596
|
|
|
|
|
|
|
|
1597
|
|
|
|
|
|
|
C<Invocant> is not exported unless requested by name. |
1598
|
|
|
|
|
|
|
|
1599
|
|
|
|
|
|
|
Recommendation: use B<Defined> from L<Types::Standard> instead. |
1600
|
|
|
|
|
|
|
|
1601
|
|
|
|
|
|
|
=head2 B<ArgsObject> |
1602
|
|
|
|
|
|
|
|
1603
|
|
|
|
|
|
|
Type::Params exports a parameterizable type constraint B<ArgsObject>. |
1604
|
|
|
|
|
|
|
It accepts the kinds of objects returned by signature checks for named |
1605
|
|
|
|
|
|
|
parameters. |
1606
|
|
|
|
|
|
|
|
1607
|
|
|
|
|
|
|
package Foo { |
1608
|
|
|
|
|
|
|
use Moo; |
1609
|
|
|
|
|
|
|
use Type::Params 'ArgsObject'; |
1610
|
|
|
|
|
|
|
|
1611
|
|
|
|
|
|
|
has args => ( |
1612
|
|
|
|
|
|
|
is => 'ro', |
1613
|
|
|
|
|
|
|
isa => ArgsObject['Bar::bar'], |
1614
|
|
|
|
|
|
|
); |
1615
|
|
|
|
|
|
|
} |
1616
|
|
|
|
|
|
|
|
1617
|
|
|
|
|
|
|
package Bar { |
1618
|
|
|
|
|
|
|
use Types::Standard -types; |
1619
|
|
|
|
|
|
|
use Type::Params 'signature'; |
1620
|
|
|
|
|
|
|
|
1621
|
|
|
|
|
|
|
sub bar { |
1622
|
|
|
|
|
|
|
state $check = signature( |
1623
|
|
|
|
|
|
|
named => [ |
1624
|
|
|
|
|
|
|
xxx => Int, |
1625
|
|
|
|
|
|
|
yyy => ArrayRef, |
1626
|
|
|
|
|
|
|
], |
1627
|
|
|
|
|
|
|
); |
1628
|
|
|
|
|
|
|
my ( $got ) = $check->( @_ ); |
1629
|
|
|
|
|
|
|
|
1630
|
|
|
|
|
|
|
return 'Foo'->new( args => $got ); |
1631
|
|
|
|
|
|
|
} |
1632
|
|
|
|
|
|
|
} |
1633
|
|
|
|
|
|
|
|
1634
|
|
|
|
|
|
|
Bar::bar( xxx => 42, yyy => [] ); |
1635
|
|
|
|
|
|
|
|
1636
|
|
|
|
|
|
|
The parameter "Bar::bar" refers to the caller when the check is compiled, |
1637
|
|
|
|
|
|
|
rather than when the parameters are checked. |
1638
|
|
|
|
|
|
|
|
1639
|
|
|
|
|
|
|
C<ArgsObject> is not exported unless requested by name. |
1640
|
|
|
|
|
|
|
|
1641
|
|
|
|
|
|
|
Recommendation: use B<Object> from L<Types::Standard> instead. |
1642
|
|
|
|
|
|
|
|
1643
|
|
|
|
|
|
|
=head1 ENVIRONMENT |
1644
|
|
|
|
|
|
|
|
1645
|
|
|
|
|
|
|
=over |
1646
|
|
|
|
|
|
|
|
1647
|
|
|
|
|
|
|
=item C<PERL_TYPE_PARAMS_XS> |
1648
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
Affects the building of accessors for C<< $arg >> objects. If set to true, |
1650
|
|
|
|
|
|
|
will use L<Class::XSAccessor>. If set to false, will use pure Perl. If this |
1651
|
|
|
|
|
|
|
environment variable does not exist, will use Class::XSAccessor. |
1652
|
|
|
|
|
|
|
|
1653
|
|
|
|
|
|
|
If Class::XSAccessor is not installed or is too old, pure Perl will always |
1654
|
|
|
|
|
|
|
be used as a fallback. |
1655
|
|
|
|
|
|
|
|
1656
|
|
|
|
|
|
|
=back |
1657
|
|
|
|
|
|
|
|
1658
|
|
|
|
|
|
|
=head1 BUGS |
1659
|
|
|
|
|
|
|
|
1660
|
|
|
|
|
|
|
Please report any bugs to |
1661
|
|
|
|
|
|
|
L<https://github.com/tobyink/p5-type-tiny/issues>. |
1662
|
|
|
|
|
|
|
|
1663
|
|
|
|
|
|
|
=head1 SEE ALSO |
1664
|
|
|
|
|
|
|
|
1665
|
|
|
|
|
|
|
L<The Type::Tiny homepage|https://typetiny.toby.ink/>. |
1666
|
|
|
|
|
|
|
|
1667
|
|
|
|
|
|
|
L<Type::Tiny>, L<Type::Coercion>, L<Types::Standard>. |
1668
|
|
|
|
|
|
|
|
1669
|
|
|
|
|
|
|
=head1 AUTHOR |
1670
|
|
|
|
|
|
|
|
1671
|
|
|
|
|
|
|
Toby Inkster E<lt>tobyink@cpan.orgE<gt>. |
1672
|
|
|
|
|
|
|
|
1673
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENCE |
1674
|
|
|
|
|
|
|
|
1675
|
|
|
|
|
|
|
This software is copyright (c) 2013-2014, 2017-2023 by Toby Inkster. |
1676
|
|
|
|
|
|
|
|
1677
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
1678
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
1679
|
|
|
|
|
|
|
|
1680
|
|
|
|
|
|
|
=head1 DISCLAIMER OF WARRANTIES |
1681
|
|
|
|
|
|
|
|
1682
|
|
|
|
|
|
|
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED |
1683
|
|
|
|
|
|
|
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
1684
|
|
|
|
|
|
|
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |