⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 validatepp.pm

📁 1. 记录每个帖子的访问人情况
💻 PM
📖 第 1 页 / 共 2 页
字号:
# Copyright (c) 2000-2004 Dave Rolsky# All rights reserved.# This program is free software; you can redistribute it and/or# modify it under the same terms as Perl itself.  See the LICENSE# file that comes with this distribution for more details.package Params::Validate;use strict;BEGIN{    sub SCALAR    () { 1 }    sub ARRAYREF  () { 2 }    sub HASHREF   () { 4 }    sub CODEREF   () { 8 }    sub GLOB      () { 16 }    sub GLOBREF   () { 32 }    sub SCALARREF () { 64 }    sub UNKNOWN   () { 128 }    sub UNDEF     () { 256 }    sub OBJECT    () { 512 }    sub HANDLE    () { 16 | 32 }    sub BOOLEAN   () { 1 | 256 }}# Various internals notes (for me and any future readers of this# monstrosity):## - A lot of the weirdness is _intentional_, because it optimizes for#   the _success_ case.  It does not really matter how slow the code is#   after it enters a path that leads to reporting failure.  But the#   "success" path should be as fast as possible.## -- We only calculate $called as needed for this reason, even though it#    means copying code all over.## - All the validation routines need to be careful never to alter the#   references that are passed.## -- The code assumes that _most_ callers will not be using the#    skip_leading or ignore_case features.  In order to not alter the#    references passed in, we copy them wholesale when normalizing them#    to make these features work.  This is slower but lets us be faster#    when not using them.# Matt Sergeant came up with this prototype, which slickly takes the# first array (which should be the caller's @_), and makes it a# reference.  Everything after is the parameters for validation.sub validate_pos (\@@){    return if $NO_VALIDATION && ! defined wantarray;    my $p = shift;    my @specs = @_;    my @p = @$p;    if ( $NO_VALIDATION )    {        # if the spec is bigger that's where we can start adding        # defaults        for ( my $x = $#p + 1; $x <= $#specs; $x++ )	{            $p[$x] =                $specs[$x]->{default}                    if ref $specs[$x] && exists $specs[$x]->{default};	}	return wantarray ? @p : \@p;    }    # I'm too lazy to pass these around all over the place.    local $options ||= _get_options( (caller(0))[0] )        unless defined $options;    my $min = 0;    while (1)    {        last unless ( ref $specs[$min] ?                      ! ( exists $specs[$min]->{default} || $specs[$min]->{optional} ) :                      $specs[$min] );	$min++;    }    my $max = scalar @specs;    my $actual = scalar @p;    unless ($actual >= $min && ( $options->{allow_extra} || $actual <= $max ) )    {	my $minmax =            ( $options->{allow_extra} ?              "at least $min" :              ( $min != $max ? "$min - $max" : $max ) );	my $val = $options->{allow_extra} ? $min : $max;	$minmax .= $val != 1 ? ' were' : ' was';        my $called = _get_called();	$options->{on_fail}->            ( "$actual parameter" .              ($actual != 1 ? 's' : '') .              " " .              ($actual != 1 ? 'were' : 'was' ) .              " passed to $called but $minmax expected\n" );    }    my $bigger = $#p > $#specs ? $#p : $#specs;    foreach ( 0..$bigger )    {	my $spec = $specs[$_];	next unless ref $spec;	if ( $_ <= $#p )	{	    my $value = defined $p[$_] ? qq|"$p[$_]"| : 'undef';	    _validate_one_param( $p[$_], \@p, $spec, "Parameter #" . ($_ + 1) . " ($value)");	}	$p[$_] = $spec->{default} if $_ > $#p && exists $spec->{default};    }    _validate_pos_depends(\@p, \@specs);    foreach ( grep { defined $p[$_] && ! ref $p[$_]                     && ref $specs[$_] && $specs[$_]{untaint} }              0..$bigger )    {        ($p[$_]) = $p[$_] =~ /(.+)/;    }    return wantarray ? @p : \@p;}sub _validate_pos_depends{    my ( $p, $specs ) = @_;    for my $p_idx ( 0..$#$p )    {        my $spec = $specs->[$p_idx];        next unless $spec && UNIVERSAL::isa( $spec, 'HASH' ) && exists $spec->{depends};        my $depends = $spec->{depends};        if ( ref $depends )        {            require Carp;            local $Carp::CarpLevel = 2;            Carp::croak( "Arguments to 'depends' for validate_pos() must be a scalar" )        }        my $p_size = scalar @$p;        if ( $p_size < $depends - 1 )        {            my $error = ( "Parameter #" . ($p_idx + 1) . " depends on parameter #" .                          $depends . ", which was not given" );            $options->{on_fail}->($error);        }    }    return 1;}sub _validate_named_depends{    my ( $p, $specs ) = @_;    foreach my $pname ( keys %$p )    {        my $spec = $specs->{$pname};        next unless $spec && UNIVERSAL::isa( $spec, 'HASH' ) && $spec->{depends};        unless ( UNIVERSAL::isa( $spec->{depends}, 'ARRAY' ) || ! ref $spec->{depends} )        {            require Carp;            local $Carp::CarpLevel = 2;            Carp::croak( "Arguments to 'depends' must be a scalar or arrayref" );        }        foreach my $depends_name ( ref $spec->{depends}                                   ? @{ $spec->{depends} }                                   : $spec->{depends} )        {            unless ( exists $p->{$depends_name} )            {                my $error = ( "Parameter '$pname' depends on parameter '" .                              $depends_name . "', which was not given" );                $options->{on_fail}->($error);            }        }    }}sub validate (\@$){    return if $NO_VALIDATION && ! defined wantarray;    my $p = $_[0];    my $specs = $_[1];    local $options = _get_options( (caller(0))[0] ) unless defined $options;    unless ( $NO_VALIDATION )    {        if ( ref $p eq 'ARRAY' )        {            # we were called as validate( @_, ... ) where @_ has a            # single element, a hash reference            if ( ref $p->[0] )            {                $p = $p->[0];            }            elsif ( @$p % 2 )            {                my $called = _get_called();                $options->{on_fail}->                    ( "Odd number of parameters in call to $called " .                      "when named parameters were expected\n" );            }            else            {                $p = {@$p};            }        }    }    if ( $options->{normalize_keys} )    {        $specs = _normalize_callback( $specs, $options->{normalize_keys} );        $p = _normalize_callback( $p, $options->{normalize_keys} );    }    elsif ( $options->{ignore_case} || $options->{strip_leading} )    {	$specs = _normalize_named($specs);	$p = _normalize_named($p);    }    if ($NO_VALIDATION)    {        return            ( wantarray ?              (               # this is a hash containing just the defaults               ( map { $_ => $specs->{$_}->{default} }                 grep { ref $specs->{$_} && exists $specs->{$_}->{default} }                 keys %$specs               ),               ( ref $p eq 'ARRAY' ?                 ( ref $p->[0] ?                   %{ $p->[0] } :                   @$p ) :                 %$p               )              ) :              do              {                  my $ref =                      ( ref $p eq 'ARRAY' ?                        ( ref $p->[0] ?                          $p->[0] :                          {@$p} ) :                        $p                      );                  foreach ( grep { ref $specs->{$_} && exists $specs->{$_}->{default} }                            keys %$specs )                  {                      $ref->{$_} = $specs->{$_}->{default}                          unless exists $ref->{$_};                  }                  return $ref;              }            );    }    _validate_named_depends($p, $specs);    unless ( $options->{allow_extra} )    {        my $called = _get_called();	if ( my @unmentioned = grep { ! exists $specs->{$_} } keys %$p )	{	    $options->{on_fail}->                ( "The following parameter" . (@unmentioned > 1 ? 's were' : ' was') .                  " passed in the call to $called but " .                  (@unmentioned > 1 ? 'were' : 'was') .                  " not listed in the validation options: @unmentioned\n" );	}    }    my @missing;    # the iterator needs to be reset in case the same hashref is being    # passed to validate() on successive calls, because we may not go    # through all the hash's elements    keys %$specs; OUTER:    while ( my ($key, $spec) = each %$specs )    {	if ( ! exists $p->{$key} &&             ( ref $spec               ? ! (                    do                    {                        # we want to short circuit the loop here if we                        # can assign a default, because there's no need                        # check anything else at all.                        if ( exists $spec->{default} )                        {                            $p->{$key} = $spec->{default};                            next OUTER;                        }                    }                    ||                    do                    {                        # Similarly, an optional parameter that is                        # missing needs no additional processing.                        next OUTER if $spec->{optional};                    }                   )               : $spec             )           )        {            push @missing, $key;	}        # Can't validate a non hashref spec beyond the presence or        # absence of the parameter.        elsif (ref $spec)        {	    my $value = defined $p->{$key} ? qq|"$p->{$key}"| : 'undef';	    _validate_one_param( $p->{$key}, $p, $spec, "The '$key' parameter ($value)" );	}    }    if (@missing)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -