1package Params::ValidationCompiler; 2 3use strict; 4use warnings; 5 6our $VERSION = '0.30'; 7 8use Params::ValidationCompiler::Compiler; 9 10use Exporter qw( import ); 11 12our @EXPORT_OK = qw( compile source_for validation_for ); 13 14sub validation_for { 15 return Params::ValidationCompiler::Compiler->new(@_)->subref; 16} 17 18## no critic (TestingAndDebugging::ProhibitNoWarnings) 19no warnings 'once'; 20*compile = \&validation_for; 21## use critic 22 23sub source_for { 24 return Params::ValidationCompiler::Compiler->new(@_)->source; 25} 26 271; 28 29# ABSTRACT: Build an optimized subroutine parameter validator once, use it forever 30 31__END__ 32 33=pod 34 35=encoding UTF-8 36 37=head1 NAME 38 39Params::ValidationCompiler - Build an optimized subroutine parameter validator once, use it forever 40 41=head1 VERSION 42 43version 0.30 44 45=head1 SYNOPSIS 46 47 use Types::Standard qw( Int Str ); 48 use Params::ValidationCompiler qw( validation_for ); 49 50 { 51 my $validator = validation_for( 52 params => { 53 foo => { type => Int }, 54 bar => { 55 type => Str, 56 optional => 1, 57 }, 58 baz => { 59 type => Int, 60 default => 42, 61 }, 62 }, 63 ); 64 65 sub foo { 66 my %args = $validator->(@_); 67 } 68 } 69 70 { 71 my $validator = validation_for( 72 params => [ 73 { type => Int }, 74 { 75 type => Str, 76 optional => 1, 77 }, 78 ], 79 ); 80 81 sub bar { 82 my ( $int, $str ) = $validator->(@_); 83 } 84 } 85 86 { 87 my $validator = validation_for( 88 params => [ 89 foo => { type => Int }, 90 bar => { 91 type => Str, 92 optional => 1, 93 }, 94 ], 95 named_to_list => 1, 96 ); 97 98 sub baz { 99 my ( $foo, $bar ) = $validator->(@_); 100 } 101 } 102 103=head1 DESCRIPTION 104 105This module creates a customized, highly efficient parameter checking 106subroutine. It can handle named or positional parameters, and can return the 107parameters as key/value pairs or a list of values. 108 109In addition to type checks, it also supports parameter defaults, optional 110parameters, and extra "slurpy" parameters. 111 112=for Pod::Coverage compile 113 114=head1 PARAMETERS 115 116This module has two options exports, C<validation_for> and C<source_for>. Both 117of these subs accept the same options: 118 119=head2 params 120 121An arrayref or hashref containing a parameter specification. 122 123If you pass a hashref then the generated validator sub will expect named 124parameters. The C<params> value should be a hashref where the parameter names 125are keys and the specs are the values. 126 127If you pass an arrayref and C<named_to_list> is false, the validator will 128expect positional params. Each element of the C<params> arrayref should be a 129parameter spec. 130 131If you pass an arrayref and C<named_to_list> is true, the validator will 132expect named params, but will return a list of values. In this case the 133arrayref should contain a I<list> of key/value pairs, where parameter names 134are the keys and the specs are the values. 135 136Each spec can contain either a boolean or hashref. If the spec is a boolean, 137this indicates required (true) or optional (false). 138 139The spec hashref accepts the following keys: 140 141=over 4 142 143=item * type 144 145A type object. This can be a L<Moose> type (from L<Moose> or 146L<MooseX::Types>), a L<Type::Tiny> type, or a L<Specio> type. 147 148If the type has coercions, those will always be used. 149 150=item * default 151 152This can either be a simple (non-reference) scalar or a subroutine 153reference. The sub ref will be called without any arguments (for now). 154 155=item * optional 156 157A boolean indicating whether or not the parameter is optional. By default, 158parameters are required unless you provide a default. 159 160=back 161 162=head2 slurpy 163 164If this is a simple true value, then the generated subroutine accepts 165additional arguments not specified in C<params>. By default, extra arguments 166cause an exception. 167 168You can also pass a type constraint here, in which case all extra arguments 169must be values of the specified type. 170 171=head2 named_to_list 172 173If this is true, the generated subroutine will expect a list of key-value 174pairs or a hashref and it will return a list containing only values. The 175C<params> you pass must be a arrayref of key-value pairs. The order of these 176pairs determines the order in which values are returned. 177 178You cannot combine C<slurpy> with C<named_to_list> as there is no way to know 179how to order the extra return values. 180 181=head2 return_object 182 183If this is true, the generated subroutine will return an object instead of a 184hashref. You cannot set this option to true if you set either or C<slurpy> or 185C<named_to_list>. 186 187The object's methods correspond to the parameter names passed to the 188subroutine. While calling methods on an object is slower than accessing a 189hashref, the advantage is that if you typo a parameter name you'll get a 190helpful error. 191 192If you have L<Class::XSAccessor> installed then this will be used to create 193the class's methods, which makes it fairly fast. 194 195The returned object is in a generated class. Do not rely on this class name 196being anything in specific, and don't check this object using C<isa>, C<DOES>, 197or anything similar. 198 199When C<return_object> is true, the parameter spec hashref also accepts to the 200following additional keys: 201 202=over 4 203 204=item * getter 205 206Use this to set an explicit getter method name for the parameter. By default 207the method name will be the same as the parameter name. Note that if the 208parameter name is not a valid sub name, then you will get an error compiling 209the validation sub unless you specify a getter for the parameter. 210 211=item * predicate 212 213Use this to ask for a predicate method to be created for this parameter. The 214predicate method returns true if the parameter was passed and false if it 215wasn't. Note that this is only useful for optional parameters, but you can ask 216for a predicate for any parameter. 217 218=back 219 220=head1 EXPORTS 221 222The exported subs are: 223 224=head2 validation_for(...) 225 226This returns a subroutine that implements the specific parameter 227checking. This subroutine expects to be given the parameters to validate in 228C<@_>. If all the parameters are valid, it will return the validated 229parameters (with defaults as appropriate), either as a list of key-value pairs 230or as a list of just values. If any of the parameters are invalid it will 231throw an exception. 232 233For validators expected named params, the generated subroutine accepts either 234a list of key-value pairs or a single hashref. Otherwise the validator expects 235a list of values. 236 237For now, you must shift off the invocant yourself. 238 239This subroutine accepts the following additional parameters: 240 241=over 4 242 243=item * name 244 245If this is given, then the generated subroutine will be named using 246L<Sub::Util>. This is strongly recommended as it makes it possible to 247distinguish different check subroutines when profiling or in stack traces. 248 249This name will also be used in some exception messages, even if L<Sub::Util> 250is not available. 251 252Note that you must install L<Sub::Util> yourself separately, as it is not 253required by this distribution, in order to avoid requiring a compiler. 254 255=item * name_is_optional 256 257If this is true, then the name is ignored when C<Sub::Util> is not 258installed. If this is false, then passing a name when L<Sub::Util> cannot be 259loaded causes an exception. 260 261This is useful for CPAN modules where you want to set a name if you can, but 262you do not want to add a prerequisite on L<Sub::Util>. 263 264=item * debug 265 266Sets the C<EVAL_CLOSURE_PRINT_SOURCE> environment variable to true before 267calling C<Eval::Closure::eval_closure()>. This causes the source of the 268subroutine to be printed before it's C<eval>'d. 269 270=back 271 272=head2 source_for(...) 273 274This returns a two element list. The first is a string containing the source 275code for the generated sub. The second is a hashref of "environment" variables 276to be used when generating the subroutine. These are the arguments that are 277passed to L<Eval::Closure>. 278 279=head1 SUPPORT 280 281Bugs may be submitted at L<https://github.com/houseabsolute/Params-ValidationCompiler/issues>. 282 283I am also usually active on IRC as 'autarch' on C<irc://irc.perl.org>. 284 285=head1 SOURCE 286 287The source code repository for Params-ValidationCompiler can be found at L<https://github.com/houseabsolute/Params-ValidationCompiler>. 288 289=head1 DONATIONS 290 291If you'd like to thank me for the work I've done on this module, please 292consider making a "donation" to me via PayPal. I spend a lot of free time 293creating free software, and would appreciate any support you'd care to offer. 294 295Please note that B<I am not suggesting that you must do this> in order for me 296to continue working on this particular software. I will continue to do so, 297inasmuch as I have in the past, for as long as it interests me. 298 299Similarly, a donation made in this way will probably not make me work on this 300software much more, unless I get so many donations that I can consider working 301on free software full time (let's all have a chuckle at that together). 302 303To donate, log into PayPal and send money to autarch@urth.org, or use the 304button at L<http://www.urth.org/~autarch/fs-donation.html>. 305 306=head1 AUTHOR 307 308Dave Rolsky <autarch@urth.org> 309 310=head1 CONTRIBUTORS 311 312=for stopwords Gregory Oschwald Tomasz Konojacki 313 314=over 4 315 316=item * 317 318Gregory Oschwald <goschwald@maxmind.com> 319 320=item * 321 322Gregory Oschwald <oschwald@gmail.com> 323 324=item * 325 326Tomasz Konojacki <me@xenu.pl> 327 328=back 329 330=head1 COPYRIGHT AND LICENSE 331 332This software is Copyright (c) 2016 - 2018 by Dave Rolsky. 333 334This is free software, licensed under: 335 336 The Artistic License 2.0 (GPL Compatible) 337 338The full text of the license can be found in the 339F<LICENSE> file included with this distribution. 340 341=cut 342