📄 check.pm
字号:
### croak with the collected errors if there were errors and ### we have the fatal flag toggled. croak(__PACKAGE__->last_error) if ($wrong || $warned) && $WARNINGS_FATAL; ### done with our loop... if $wrong is set, somethign went wrong ### and the user is already informed, just return... return if $wrong; ### check if we need to store any of the keys ### ### can't do it before, because something may go wrong later, ### leaving the user with a few set variables for my $key (keys %defs) { if( my $ref = $utmpl{$key}->{'store'} ) { $$ref = $NO_DUPLICATES ? delete $defs{$key} : $defs{$key}; } } return \%defs;}=head2 allow( $test_me, \@criteria );The function that handles the C<allow> key in the template is alsoavailable for independent use.The function takes as first argument a key to test against, andas second argument any form of criteria that are also allowed bythe C<allow> key in the template.You can use the following types of values for allow:=over 4=item stringThe provided argument MUST be equal to the string for the validationto pass.=item regexpThe provided argument MUST match the regular expression for thevalidation to pass.=item subroutineThe provided subroutine MUST return true in order for the validationto pass and the argument accepted.(This is particularly useful for more complicated data).=item array refThe provided argument MUST equal one of the elements of the arrayref for the validation to pass. An array ref can hold all the abovevalues.=backIt returns true if the key matched the criteria, or false otherwise.=cutsub allow { ### use $_[0] and $_[1] since this is hot code... ### #my ($val, $ref) = @_; ### it's a regexp ### if( ref $_[1] eq 'Regexp' ) { local $^W; # silence warnings if $val is undef # return if $_[0] !~ /$_[1]/; ### it's a sub ### } elsif ( ref $_[1] eq 'CODE' ) { return unless $_[1]->( $_[0] ); ### it's an array ### } elsif ( ref $_[1] eq 'ARRAY' ) { ### loop over the elements, see if one of them says the ### value is OK ### also, short-cicruit when possible for ( @{$_[1]} ) { return 1 if allow( $_[0], $_ ); } return; ### fall back to a simple, but safe 'eq' ### } else { return unless _safe_eq( $_[0], $_[1] ); } ### we got here, no failures ### return 1;}### helper functions ###### clean up the template ###sub _clean_up_args { ### don't even bother to loop, if there's nothing to clean up ### return $_[0] if $PRESERVE_CASE and !$STRIP_LEADING_DASHES; my %args = %{$_[0]}; ### keys are note aliased ### for my $key (keys %args) { my $org = $key; $key = lc $key unless $PRESERVE_CASE; $key =~ s/^-// if $STRIP_LEADING_DASHES; $args{$key} = delete $args{$org} if $key ne $org; } ### return references so we always return 'true', even on empty ### arguments return \%args;}sub _sanity_check_and_defaults { my %utmpl = %{$_[0]}; my %args = %{$_[1]}; my $verbose = $_[2]; my %defs; my $fail; for my $key (keys %utmpl) { ### check if required keys are provided ### keys are now lower cased, unless preserve case was enabled ### at which point, the utmpl keys must match, but that's the users ### problem. if( $utmpl{$key}->{'required'} and not exists $args{$key} ) { _store_error( loc(q|Required option '%1' is not provided for %2 by %3|, $key, _who_was_it(1), _who_was_it(2)), $verbose ); ### mark the error ### $fail++; next; } ### next, set the default, make sure the key exists in %defs ### $defs{$key} = $utmpl{$key}->{'default'} if exists $utmpl{$key}->{'default'}; if( $SANITY_CHECK_TEMPLATE ) { ### last, check if they provided any weird template keys ### -- do this last so we don't always execute this code. ### just a small optimization. map { _store_error( loc(q|Template type '%1' not supported [at key '%2']|, $_, $key), 1, 1 ); } grep { not $known_keys{$_} } keys %{$utmpl{$key}}; ### make sure you passed a ref, otherwise, complain about it! if ( exists $utmpl{$key}->{'store'} ) { _store_error( loc( q|Store variable for '%1' is not a reference!|, $key ), 1, 1 ) unless ref $utmpl{$key}->{'store'}; } } } ### errors found ### return if $fail; ### return references so we always return 'true', even on empty ### defaults return \%defs;}sub _safe_eq { ### only do a straight 'eq' if they're both defined ### return defined($_[0]) && defined($_[1]) ? $_[0] eq $_[1] : defined($_[0]) eq defined($_[1]);}sub _who_was_it { my $level = $_[0] || 0; return (caller(2 + $CALLER_DEPTH + $level))[3] || 'ANON'}=head2 last_error()Returns a string containing all warnings and errors reported duringthe last time C<check> was called.This is useful if you want to report then some other way thanC<carp>'ing when the verbose flag is on.It is exported upon request.=cut{ $_ERROR_STRING = ''; sub _store_error { my($err, $verbose, $offset) = @_[0..2]; $verbose ||= 0; $offset ||= 0; my $level = 1 + $offset; local $Carp::CarpLevel = $level; carp $err if $verbose; $_ERROR_STRING .= $err . "\n"; } sub _clear_error { $_ERROR_STRING = ''; } sub last_error { $_ERROR_STRING }}1;=head1 Global VariablesThe behaviour of Params::Check can be altered by changing thefollowing global variables:=head2 $Params::Check::VERBOSEThis controls whether Params::Check will issue warnings andexplanations as to why certain things may have failed.If you set it to 0, Params::Check will not output any warnings.The default is 1 when L<warnings> are enabled, 0 otherwise;=head2 $Params::Check::STRICT_TYPEThis works like the C<strict_type> option you can pass to C<check>,which will turn on C<strict_type> globally for all calls to C<check>.The default is 0;=head2 $Params::Check::ALLOW_UNKNOWNIf you set this flag, unknown options will still be present in thereturn value, rather than filtered out. This is useful if yoursubroutine is only interested in a few arguments, and wants to passthe rest on blindly to perhaps another subroutine.The default is 0;=head2 $Params::Check::STRIP_LEADING_DASHESIf you set this flag, all keys passed in the following manner: function( -key => 'val' );will have their leading dashes stripped.=head2 $Params::Check::NO_DUPLICATESIf set to true, all keys in the template that are marked as to bestored in a scalar, will also be removed from the result set.Default is false, meaning that when you use C<store> as a templatekey, C<check> will put it both in the scalar you supplied, as well asin the hashref it returns.=head2 $Params::Check::PRESERVE_CASEIf set to true, L<Params::Check> will no longer convert all keys fromthe user input to lowercase, but instead expect them to be in thecase the template provided. This is useful when you want to usesimilar keys with different casing in your templates.Understand that this removes the case-insensitivy feature of thismodule.Default is 0;=head2 $Params::Check::ONLY_ALLOW_DEFINEDIf set to true, L<Params::Check> will require all values passed to beC<defined>. If you wish to enable this on a 'per key' basis, use thetemplate option C<defined> instead.Default is 0;=head2 $Params::Check::SANITY_CHECK_TEMPLATEIf set to true, L<Params::Check> will sanity check templates, validatingfor errors and unknown keys. Although very useful for debugging, thiscan be somewhat slow in hot-code and large loops.To disable this check, set this variable to C<false>.Default is 1;=head2 $Params::Check::WARNINGS_FATALIf set to true, L<Params::Check> will C<croak> when an error during template validation occurs, rather than return C<false>.Default is 0;=head2 $Params::Check::CALLER_DEPTHThis global modifies the argument given to C<caller()> byC<Params::Check::check()> and is useful if you have a custom wrapperfunction around C<Params::Check::check()>. The value must be aninteger, indicating the number of wrapper functions inserted betweenthe real function call and C<Params::Check::check()>.Example wrapper function, using a custom stacktrace: sub check { my ($template, $args_in) = @_; local $Params::Check::WARNINGS_FATAL = 1; local $Params::Check::CALLER_DEPTH = $Params::Check::CALLER_DEPTH + 1; my $args_out = Params::Check::check($template, $args_in); my_stacktrace(Params::Check::last_error) unless $args_out; return $args_out; }Default is 0;=head1 AUTHORThis module byJos Boumans E<lt>kane@cpan.orgE<gt>.=head1 AcknowledgementsThanks to Richard Soderberg for his performance improvements.=head1 COPYRIGHTThis module iscopyright (c) 2003,2004 Jos Boumans E<lt>kane@cpan.orgE<gt>.All rights reserved.This library is free software;you may redistribute and/or modify it under the sameterms as Perl itself.=cut# Local variables:# c-indentation-style: bsd# c-basic-offset: 4# indent-tabs-mode: nil# End:# vim: expandtab shiftwidth=4:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -