|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package FormValidator::Tiny;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $FormValidator::Tiny::VERSION = '0.002';  | 
| 
3
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
3611743
 | 
 use v5.18;  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
90
 | 
    | 
| 
4
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
126
 | 
 use warnings;  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
689
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
122
 | 
 use List::Util qw( any pairs pairgrep pairmap );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1644
 | 
    | 
| 
7
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
131
 | 
 use Scalar::Util qw( blessed looks_like_number );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1182
 | 
    | 
| 
8
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
6327
 | 
 use experimental qw( regex_sets );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62749
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
142
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
10
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
1644
 | 
 use Exporter;  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2690
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 BEGIN {  | 
| 
13
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
316
 | 
     our @ISA = qw( Exporter );  | 
| 
14
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
     our @EXPORT = qw( validation_spec validate_form );  | 
| 
15
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
     my @export_predicates = qw(  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         limit_character_set  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         length_in_range  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         equal_to  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         number_in_range  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
21
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
     my @export_filters = qw(  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         split_by  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         trim  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
25
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
105
 | 
     our @EXPORT_OK = (@export_predicates, @export_filters);  | 
| 
26
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25741
 | 
     our %EXPORT_TAGS = (  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         validation => \@EXPORT,  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         predicates => \@export_predicates,  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         filters    => \@export_filters,  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ABSTRACT: A tiny form validator  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %coercer = (  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     '+'     => sub { (1, '', 0+$_[0]) },  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     '?'     => sub { (1, '', length($_[0]) > 0) },  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     '?+'    => sub { (1, '', !!(0+$_[0])) },  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     '?perl' => sub { (1, '', !!$_[0]) },  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     '[]'    => sub { (1, '', [ _listy($_[0]) ]) },  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     '{}'    => sub { (1, '', ref $_[0] ? +{ _listy($_[0]) } : { $_[0] => $_[0] })  },  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _sub_coercer {  | 
| 
45
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
3
 | 
     my ($sub) = @_;  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
47
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
2
 | 
         local $_ = $_[0];  | 
| 
48
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         my $into = $sub->(@_);  | 
| 
49
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         (1, '', $into);  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
51
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 }  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _yes_no_coercer {  | 
| 
54
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
10
 | 
     my ($yes, $no) = @_;  | 
| 
55
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     my $fcyes = fc $yes;  | 
| 
56
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my $fcno  = fc $no;  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
58
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
7
 | 
         my $fc_ = fc $_[0];  | 
| 
59
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
         my $truth = $fc_ eq $fcyes ? 1  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   : $fc_ eq $fcno  ? 0  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   :                  undef;  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
63
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         return (defined $truth, qq[Enter "$yes" or "$no".], $truth);  | 
| 
64
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     };  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _package_coercer {  | 
| 
68
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
     my ($package) = @_;  | 
| 
69
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
21
 | 
     sub { (1, '', $package->new($_[0])) }  | 
| 
70
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 }  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _type_coercer {  | 
| 
73
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
     my ($type) = @_;  | 
| 
74
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
9
 | 
     sub { (1, '', $type->coerce($_[0])) }  | 
| 
75
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 }  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _sub_validator {  | 
| 
78
 | 
17
 | 
 
 | 
 
 | 
  
17
  
 | 
 
 | 
38
 | 
     my ($sub) = @_;  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
80
 | 
56
 | 
  
100
  
 | 
 
 | 
  
56
  
 | 
 
 | 
144
 | 
         return (1, '', $_[0]) unless defined $_[0];  | 
| 
81
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
99
 | 
         local $_ = $_[0];  | 
| 
82
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
170
 | 
         my ($valid, $error) = $sub->(@_);  | 
| 
83
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
352
 | 
         ($valid, $error, $_[0]);  | 
| 
84
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
96
 | 
     };  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _re_validator {  | 
| 
88
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
19
 | 
     my ($re) = @_;  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
90
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
11
 | 
         my ($value) = @_;  | 
| 
91
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
         return (1, '', $value) unless defined $value;  | 
| 
92
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
         my $valid = $value =~ /$re/;  | 
| 
93
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
         ($valid, 'Incorrect.', $value);  | 
| 
94
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
     };  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _type_validator {  | 
| 
98
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
6
 | 
     my ($type) = @_;  | 
| 
99
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     if ($type->can('check')) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
100
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
770
 | 
         my $message = $type->can('get_message') ? sub { $type->get_message($_[0]) }  | 
| 
101
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
                     :                             'Incorrect.';  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {  | 
| 
104
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
6
 | 
             my ($value) = @_;  | 
| 
105
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
             return (1, '', $value) unless defined $value;  | 
| 
106
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
             my $valid = $type->check($value);  | 
| 
107
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
             ($valid, $message, $value);  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
109
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     }  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($type->can('validate')) {  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {  | 
| 
112
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
4
 | 
             my ($value) = @_;  | 
| 
113
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
             return (1, '', $value) unless defined $value;  | 
| 
114
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
             my $message = $type->validate($value);  | 
| 
115
 | 
2
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
13
 | 
             (!defined $message, $message//'', $value);  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
117
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     }  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
119
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     die "bad type encountered"; # uncoverable statement  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _with_error {  | 
| 
123
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
7
 | 
     my ($decl, $with_error) = @_;  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
125
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
11
 | 
         my ($valid, $decl_message, $value) = $decl->(@_);  | 
| 
126
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
         ($valid, $with_error, $value);  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
128
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
 }  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _listy {  | 
| 
131
 | 
78
 | 
 
 | 
 
 | 
  
78
  
 | 
 
 | 
167
 | 
     my ($stuff) = @_;  | 
| 
132
 | 
78
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
419
 | 
     return @$stuff if 'ARRAY' eq ref $stuff;  | 
| 
133
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
206
 | 
     return %$stuff if 'HASH'  eq ref $stuff;  | 
| 
134
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     return ($stuff);  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _ytsil {  | 
| 
138
 | 
30
 | 
 
 | 
 
 | 
  
30
  
 | 
 
 | 
71
 | 
     my ($old_stuff, $new_stuff) = @_;  | 
| 
139
 | 
30
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
116
 | 
     return $new_stuff      if 'ARRAY' eq ref $old_stuff;  | 
| 
140
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
120
 | 
     return { @$new_stuff } if 'HASH'  eq ref $old_stuff;  | 
| 
141
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $new_stuff->[0];  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _for_each {  | 
| 
145
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
15
 | 
     my ($element, $decl_sub) = @_;  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
147
 | 
6
 | 
  
100
  
 | 
 
 | 
  
20
  
 | 
 
 | 
37
 | 
     my $lister = $element eq 'each' ? sub { _listy($_[0]) } : sub { pairs(_listy($_[0])) };  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
    | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
    | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
149
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     my ($puller, $pusher);  | 
| 
150
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     if ($element eq 'key') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
151
 | 
2
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
8
 | 
         $puller = sub { $_[0][0] };          # pull key from pairs()  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
    | 
| 
152
 | 
2
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
8
 | 
         $pusher = sub { ($_[1], $_[0][1]) }; # push updated key, original value from pairs()  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($element eq 'value') {  | 
| 
155
 | 
2
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
7
 | 
         $puller = sub { $_[0][1] };          # pull value from pairs()  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
    | 
| 
156
 | 
2
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
8
 | 
         $pusher = sub { ($_[0][0], $_[1]) }; # push original key from pairs(), updated value  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
    | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else { # $element eq 'each'  | 
| 
159
 | 
2
 | 
 
 | 
 
 | 
  
16
  
 | 
 
 | 
8
 | 
         $puller = sub { $_[0] };             # pull value from _listy()  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
    | 
| 
160
 | 
2
 | 
 
 | 
 
 | 
  
16
  
 | 
 
 | 
7
 | 
         $pusher = sub { $_[1] };             # push updated element  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
    | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
164
 | 
30
 | 
 
 | 
 
 | 
  
30
  
 | 
 
 | 
68
 | 
         my ($stuff) = @_;  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
166
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
         my $valid = 1;  | 
| 
167
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
         my $error = '';  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my @new_stuff = map {  | 
| 
169
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
80
 | 
             my $update_value = $puller->($_);  | 
| 
 
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
87
 | 
    | 
| 
170
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
85
 | 
             my ($element_valid, $element_error, $element_value) = $decl_sub->($update_value);  | 
| 
171
 | 
32
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
91
 | 
             unless ($element_valid) {  | 
| 
172
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
                 $valid   = 0;  | 
| 
173
 | 
16
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
55
 | 
                 $error ||= $element_error;  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
175
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
95
 | 
             $pusher->($_, $element_value);  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } $lister->($stuff);  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
178
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
103
 | 
         return ($valid, $error, _ytsil($stuff, \@new_stuff));  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
180
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
 }  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # lifted from perldoc perldata  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $NAME_RE = qr/ (?[ ( \p{Word} & \p{XID_Start} ) + [_] ])  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   (?[ ( \p{Word} & \p{XID_Continue} ) ]) *    /x;  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $PACKAGE_RE = qr/^ $NAME_RE (?: ('|::) $NAME_RE )* $/x;  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _locate_package_name {  | 
| 
188
 | 
39
 | 
 
 | 
 
 | 
  
39
  
 | 
 
 | 
107
 | 
     my ($spec_name, $depth) = @_;  | 
| 
189
 | 
39
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
234
 | 
     $depth //= 1;  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
191
 | 
39
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
379
 | 
     die "name must be a valid Perl identifier"  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unless $spec_name =~ /$PACKAGE_RE/;  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
194
 | 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
94
 | 
     my ($package, $name);  | 
| 
195
 | 
39
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
198
 | 
     if ($spec_name =~ /\b(::|')\b/) {  | 
| 
196
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         my @parts = split /::|'/, $spec_name;  | 
| 
197
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         $name = pop @parts;  | 
| 
198
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         $package = join '::', @parts;  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
201
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
262
 | 
         ($package) = caller($depth);  | 
| 
202
 | 
38
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
137
 | 
         $package //='main';  | 
| 
203
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
87
 | 
         $name      = $spec_name;  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
206
 | 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
116
 | 
     $package .= '::FORM_VALIDATOR_TINY_SPECIFICATION';  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {  | 
| 
208
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
60896
 | 
         no strict 'refs';  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
188
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20676
 | 
    | 
| 
 
 | 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
68
 | 
    | 
| 
209
 | 
39
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
78
 | 
         ${ $package } //= {};  | 
| 
 
 | 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
246
 | 
    | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
212
 | 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
153
 | 
     ($package, $name);  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub validation_spec($;$) {  | 
| 
216
 | 
40
 | 
 
 | 
 
 | 
  
40
  
 | 
  
1
  
 | 
30897
 | 
     my ($name, $spec) = @_;  | 
| 
217
 | 
40
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
166
 | 
     if (ref $name) {  | 
| 
218
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
         $spec = $name;  | 
| 
219
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
         undef $name;  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
222
 | 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
     my $error;  | 
| 
223
 | 
40
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
130
 | 
     if (defined $name) {  | 
| 
224
 | 
17
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
116
 | 
         $error = sub { die "spec [$name] ", @_ };  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
    | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
227
 | 
23
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
63
 | 
         if (!defined wantarray) {  | 
| 
228
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
             die "useless call to validation_spec with no name in void context";  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
230
 | 
22
 | 
 
 | 
 
 | 
  
21
  
 | 
 
 | 
110
 | 
         $error = sub { die "spec ", @_ };  | 
| 
 
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
367
 | 
    | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
233
 | 
39
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
165
 | 
     $error->("must be an array reference")  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unless 'ARRAY' eq ref $spec;  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
236
 | 
38
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
155
 | 
     $error->("contains odd number of elements")  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unless scalar @$spec % 2 == 0;  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
239
 | 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
96
 | 
     my @decl_spec;  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my %encountered_fields;  | 
| 
241
 | 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
375
 | 
     for my $field_pair (pairs @$spec) {  | 
| 
242
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
244
 | 
         my ($field, $decls) = @$field_pair;  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
244
 | 
58
 | 
 
 | 
 
 | 
  
20
  
 | 
 
 | 
267
 | 
         my $error = sub { $error->("input declaration for [$field] ", @_) };  | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
    | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
246
 | 
58
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
203
 | 
         $error->("has been defined twice") if $encountered_fields{ $field };  | 
| 
247
 | 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
159
 | 
         $encountered_fields{ $field }++;  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
249
 | 
57
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
212
 | 
         $error->("must be in an array reference")  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             unless 'ARRAY' eq ref $decls;  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
252
 | 
56
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
169
 | 
         $error->("contains odd number of elements")  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             unless scalar @$decls % 2 == 0;  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
         my %options;  | 
| 
256
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
132
 | 
         my @decl = (\%options);  | 
| 
257
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
317
 | 
         for my $decl_pair (pairs @$decls) {  | 
| 
258
 | 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
227
 | 
             my ($op, $arg) = @$decl_pair;  | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
260
 | 
82
 | 
  
100
  
 | 
  
100
  
 | 
  
229
  
 | 
 
 | 
392
 | 
             if (any { $op eq $_ } qw( from multiple trim )) {  | 
| 
 
 | 
229
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
943
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
261
 | 
17
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
72
 | 
                 $error->("found [$op] after filter or validation declarations")  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     if @decl > 1;  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $error->("has more than one [$op] declaration")  | 
| 
265
 | 
14
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
68
 | 
                     if defined $options{ $op };  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
267
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
                 $options{ $op } = $arg;  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             elsif ($op =~ /^ (?: (each|key|value)_ )? into $/x) {  | 
| 
271
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
                 my $element = $1;  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
273
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
129
 | 
                 my $into_sub;  | 
| 
274
 | 
24
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
239
 | 
                 if ('CODE' eq ref $arg) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
275
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
                     $into_sub = _sub_coercer($arg);  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif (blessed $arg && $arg->can('coerce')) {  | 
| 
278
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
                     $into_sub = _type_coercer($arg);  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif (defined $coercer{ $arg }) {  | 
| 
281
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
                     $into_sub = $coercer{ $arg };  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif ($arg =~ /\?([^!]+)!(.+)/) {  | 
| 
284
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
                     $into_sub = _yes_no_coercer($1, $2);  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif ($arg =~ $PACKAGE_RE) {  | 
| 
287
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
                     $into_sub = _package_coercer($arg);  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 else {  | 
| 
290
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
                     $error->("has unknown [$op] declaration argument [$arg]");  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
293
 | 
20
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
64
 | 
                 $into_sub = _for_each($element, $into_sub) if $element;  | 
| 
294
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
92
 | 
                 push @decl, $into_sub;  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             elsif ($op eq 'required' || $op eq 'optional') {  | 
| 
298
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
                 $arg = !$arg if $op eq 'optional';  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # Validate on required  | 
| 
301
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
                 if ($arg) {  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     push @decl, sub {  | 
| 
303
 | 
10
 | 
 
 | 
  
 66
  
 | 
  
10
  
 | 
 
 | 
41
 | 
                         my $valid = (defined $_[0] && $_[0] =~ /./);  | 
| 
304
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
                         ($valid, 'Required.', $_[0])  | 
| 
305
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
                     };  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # Shortcircuit on optional  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 else {  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     push @decl, sub {  | 
| 
311
 | 
10
 | 
  
100
  
 | 
  
 66
  
 | 
  
10
  
 | 
 
 | 
48
 | 
                         my $valid = (defined $_[0] && $_[0] =~ /./) ? 1 : undef;  | 
| 
312
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
                         ($valid, '', $_[0])  | 
| 
313
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
                     };  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             elsif ($op =~ /^ (?: (each|key|value)_ )? must $/x) {  | 
| 
318
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
96
 | 
                 my $element = $1;  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
320
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
110
 | 
                 my $must_sub;  | 
| 
321
 | 
31
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
153
 | 
                 if ('CODE' eq ref $arg) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
322
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
                     $must_sub = _sub_validator($arg);  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif ('Regexp' eq ref $arg) {  | 
| 
325
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
                     $must_sub = _re_validator($arg);  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif (blessed $arg && ($arg->can('check') || $arg->can('validate'))) {  | 
| 
328
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
                     $must_sub = _type_validator($arg);  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 else {  | 
| 
331
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
                     $error->("has unknown [$op] declaration argument [$arg]");  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
334
 | 
26
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
87
 | 
                 $must_sub = _for_each($element, $must_sub) if $element;  | 
| 
335
 | 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
                 push @decl, $must_sub;  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             elsif ($op eq 'with_error') {  | 
| 
339
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
                 $error->("has [$op] before a declaration in which it may modify")  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     unless @decl > 1;  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
342
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
                 my $last_decl = pop @decl;  | 
| 
343
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
                 push @decl, _with_error($last_decl, $arg);  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
347
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
                 $error->("has unknown [$op]");  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
351
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
286
 | 
         push @decl_spec, $field, \@decl;  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
354
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
     my $finished_spec = \@decl_spec;  | 
| 
355
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
80
 | 
     bless $finished_spec, __PACKAGE__;  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
357
 | 
17
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
69
 | 
     if (defined $name) {  | 
| 
358
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
         my $package;  | 
| 
359
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
         ($package, $name) = _locate_package_name($name);  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         {  | 
| 
362
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
300
 | 
             no strict 'refs';  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4841
 | 
    | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
    | 
| 
363
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
             ${ $package }->{ $name } = $finished_spec;  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
    | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
367
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
112
 | 
     return $finished_spec;  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub validate_form($$) {  | 
| 
371
 | 
28
 | 
 
 | 
 
 | 
  
28
  
 | 
  
1
  
 | 
48243
 | 
     my ($name, $input) = @_;  | 
| 
372
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
     my @input;  | 
| 
373
 | 
28
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
166
 | 
     if (blessed $input && $input->can('flatten')) {  | 
| 
374
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         @input = $input->flatten;  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
377
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
         @input = _listy($input);  | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
380
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
     my $spec = $name;  | 
| 
381
 | 
28
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
186
 | 
     unless (blessed $spec && $spec->isa(__PACKAGE__)) {  | 
| 
382
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
         my $package;  | 
| 
383
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
78
 | 
         ($package, $name) = _locate_package_name($name);  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         {  | 
| 
386
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
157
 | 
             no strict 'refs';  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41575
 | 
    | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
    | 
| 
387
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
             $spec = ${ $package }->{ $name };  | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
    | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
389
 | 
23
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
85
 | 
             die "no spec with name [$name] found in package [$package]"  | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 unless defined $spec;  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
394
 | 
28
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
86
 | 
     die "no spec provided to validate with" unless defined $spec;  | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
396
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
     my (%params, %errors);  | 
| 
397
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
311
 | 
     FIELD: for my $field_pair (pairs @$spec) {  | 
| 
398
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
499
 | 
         my ($field, $decls) = @$field_pair;  | 
| 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
400
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
143
 | 
         my $field_input;  | 
| 
401
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
195
 | 
         DECL_FOR_FIELD: for my $decl (@$decls) {  | 
| 
402
 | 
221
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
518
 | 
             if ('HASH' eq ref $decl) {  | 
| 
403
 | 
91
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
365
 | 
                 my $from     = $decl->{from}     // $field;  | 
| 
404
 | 
91
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
298
 | 
                 my $multiple = $decl->{multiple} // 0;  | 
| 
405
 | 
91
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
301
 | 
                 my $trim     = $decl->{trim}     // 1;  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
407
 | 
91
 | 
 
 | 
 
 | 
  
500
  
 | 
 
 | 
731
 | 
                 my @values = pairmap { $b } pairgrep { $a eq $from } @input;  | 
| 
 
 | 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
280
 | 
    | 
| 
 
 | 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1066
 | 
    | 
| 
408
 | 
91
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
450
 | 
                 @values = map { if (defined) { s/^\s+//; s/\s+$// } $_ } @values if $trim;  | 
| 
 
 | 
108
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
255
 | 
    | 
| 
 
 | 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
332
 | 
    | 
| 
 
 | 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
234
 | 
    | 
| 
 
 | 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
330
 | 
    | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
410
 | 
91
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
228
 | 
                 if ($multiple) {  | 
| 
411
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
                     $field_input = \@values;  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 else {  | 
| 
414
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
127
 | 
                     $field_input = pop @values;  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
419
 | 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
320
 | 
                 my ($valid, $error, $new_value) = $decl->($field_input, \%params);  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
421
 | 
130
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
418
 | 
                 if (!defined $valid) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
422
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
                     $field_input = undef;  | 
| 
423
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
                     last DECL_FOR_FIELD;  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif ($valid) {  | 
| 
426
 | 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
240
 | 
                     $field_input = $new_value;  | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 else {  | 
| 
429
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
                     $field_input = undef;  | 
| 
430
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
                     push @{ $errors{ $field } }, $error;  | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
    | 
| 
431
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
                     last DECL_FOR_FIELD;  | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
436
 | 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
276
 | 
         $params{ $field } = $field_input;  | 
| 
437
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
439
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
138
 | 
     my $errors = scalar keys %errors ? \%errors : undef;  | 
| 
440
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
134
 | 
     return (\%params, $errors);  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
443
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _comma_and {  | 
| 
444
 | 
9
 | 
  
 50
  
 | 
 
 | 
  
9
  
 | 
 
 | 
38
 | 
     if (@_ == 0) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
445
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         return '';  | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif (@_ == 1) {  | 
| 
448
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
         return $_[0];  | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif (@_ == 2) {  | 
| 
451
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
         return "$_[0] and $_[1]";  | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
454
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         my $last = pop @_;  | 
| 
455
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
         return join(", ", @_) . ", and " . $last  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
459
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub limit_character_set {  | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $_build_class = sub {  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my @class_parts = map {  | 
| 
462
 | 
13
 | 
  
100
  
 | 
  
100
  
 | 
  
13
  
 | 
 
 | 
24
 | 
             if (1 == length $_) {  | 
| 
 
 | 
20
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
134
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
463
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
                 [ "[$_]", qq["$_"] ]  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             elsif (/^(.)-(.)$/ && ord($1) < ord($2)) {  | 
| 
466
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
                 [ "[$_]", qq["$1" through "$2"] ]  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             elsif (/^\[([^\]]+)\]$/) {  | 
| 
469
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
                 my $name = my $prop = $1;  | 
| 
470
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
                 $name =~ s/_/ /g;  | 
| 
471
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
                 [ "\\p{$prop}", qq[\L$name\E characters] ]  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
474
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
                 die "invalid character set [$_]";  | 
| 
475
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } @_;  | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
478
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
         my $classes = join ' + ', map { $_->[0] } @class_parts;  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
    | 
| 
479
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
344
 | 
         my $re = qr/(?[ $classes ])/x;  | 
| 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
481
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1018
 | 
         my $error = _comma_and(map { $_->[1] } @class_parts);  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
    | 
| 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
483
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
         return ($re, $error);  | 
| 
484
 | 
11
 | 
 
 | 
 
 | 
  
11
  
 | 
  
1
  
 | 
12788
 | 
     };  | 
| 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
486
 | 
11
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
77
 | 
     if (@_ == 2 && 'ARRAY' eq ref $_[0] && 'ARRAY' eq ref $_[1]) {  | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
487
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         my ($first_re, $first_error) = $_build_class->(@{ $_[0] });  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
488
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         my ($rest_re, $rest_error)   = $_build_class->(@{ $_[1] });  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
490
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         my $error = "First character only permits: "  | 
| 
491
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   . $first_error . ". Remaining only permits: "  | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   . $rest_error;  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sub {  | 
| 
495
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1486
 | 
             my ($value) = @_;  | 
| 
496
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
             my $valid = ($value =~ /^(?:$first_re$rest_re*)?$/);  | 
| 
497
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
             ($valid, $error);  | 
| 
498
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
         };  | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
501
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
         my ($re, $error) = $_build_class->(@_);  | 
| 
502
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
503
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
         $error = "Only permits: "  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                . $error;  | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sub {  | 
| 
507
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
1855
 | 
             my ($value) = @_;  | 
| 
508
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
295
 | 
             my $valid = ($value =~ /^$re*$/);  | 
| 
509
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
398
 | 
             ($valid, $error);  | 
| 
510
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
90
 | 
         };  | 
| 
511
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
513
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub length_in_range {  | 
| 
515
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
6615
 | 
     my ($start, $stop) = @_;  | 
| 
516
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
517
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
66
 | 
     die "minimum length in length_in_range must be a positive integer, got [$start] instead"  | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unless $start =~ /^(?:[0-9]+|\*)$/;  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
520
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     die "maximum length in length_in_range must be a positive integer, got [$stop] instead"  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unless $stop =~ /^(?:[0-9]+|\*)$/;  | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
523
 | 
6
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
43
 | 
     die "minimum length must be less than or equal to maximum length in length_in_range, got [$start>$stop] instead"  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if $start ne '*' && $stop ne '*' && $start > $stop;  | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
526
 | 
5
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
44
 | 
     if ($start eq '*' && $stop eq '*') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
527
 | 
1
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
6
 | 
         return sub { (1, '') };  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
362
 | 
    | 
| 
528
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
529
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($start eq '*') {  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {  | 
| 
531
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
329
 | 
             my $valid = length $_[0] <= $stop;  | 
| 
532
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
             ($valid, "Must be no longer than $stop characters.")  | 
| 
533
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
         };  | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($stop eq '*') {  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {  | 
| 
537
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
630
 | 
             my $valid = length $_[0] >= $start;  | 
| 
538
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
             ($valid, "Must be at least $start characters long.")  | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
540
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     }  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
542
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {  | 
| 
543
 | 
5
 | 
  
 50
  
 | 
 
 | 
  
5
  
 | 
 
 | 
690
 | 
             return (1, '') unless defined $_[0];  | 
| 
544
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
13
 | 
             if (length $_[0] >= $start) {  | 
| 
545
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
                 my $valid = length $_[0] <= $stop;  | 
| 
546
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
                 return ($valid, "Must be no longer than $stop characters.");  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
549
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
                 return ('', "Must be at least $start characters in length.")  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
552
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     }  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
555
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub equal_to {  | 
| 
556
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
78
 | 
     my ($field_name) = @_;  | 
| 
557
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
559
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
5108
 | 
         ($_[0] eq $_[1]{ $field_name }, "The value must match $field_name.")  | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
561
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 }  | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub number_in_range {  | 
| 
564
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
7329
 | 
     my $start = shift;  | 
| 
565
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     my $stop  = shift;  | 
| 
566
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     my $starti = 1;  | 
| 
567
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     my $stopi  = 1;  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
569
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
     if ($start eq 'exclusive') {  | 
| 
570
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
         $starti = 0;  | 
| 
571
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
         $start  = $stop;  | 
| 
572
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         $stop   = shift;  | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
574
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
575
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     if ($stop eq 'exclusive') {  | 
| 
576
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
         $stopi = 0;  | 
| 
577
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
         $stop  = shift;  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
580
 | 
9
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
68
 | 
     die "minimum length in length_in_range must be a positive integer, got [$start] instead"  | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unless $start eq '*' || looks_like_number($start);  | 
| 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
583
 | 
8
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
48
 | 
     die "maximum length in length_in_range must be a positive integer, got [$stop] instead"  | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unless $stop eq '*' || looks_like_number($stop);  | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
586
 | 
7
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
50
 | 
     die "minimum length must be less than or equal to maximum length in length_in_range, got [$start>$stop] instead"  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if $start ne '*' && $stop ne '*' && $start > $stop;  | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
589
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
1067
 | 
     my $check_start = $starti ? sub { (($_[0] >= $start), "Number must be at least $start.") }  | 
| 
590
 | 
6
 | 
  
100
  
 | 
 
 | 
  
2
  
 | 
 
 | 
35
 | 
                     :           sub { (($_[0] > $start),  "Number must be greater than $start.") };  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
591
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
620
 | 
     my $check_stop  = $stopi  ? sub { (($_[0] <= $stop),  "Number must be no more than $stop.") }  | 
| 
592
 | 
6
 | 
  
100
  
 | 
 
 | 
  
1
  
 | 
 
 | 
27
 | 
                     :           sub { (($_[0] < $stop),   "Number must be less than $stop.") };  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
    | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
594
 | 
6
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
35
 | 
     if ($start eq '*' && $stop eq '*') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
595
 | 
1
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
8
 | 
         return sub { (1, '') };  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
554
 | 
    | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($start eq '*') {  | 
| 
598
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         return $check_stop;  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($stop eq '*') {  | 
| 
601
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
         return $check_start;  | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
603
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {  | 
| 
605
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
2371
 | 
             my ($v, $e) = $check_start->(@_);  | 
| 
606
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
             return ($v, $e) unless $v;  | 
| 
607
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
             return $check_stop->(@_);  | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
609
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     }  | 
| 
610
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub split_by {  | 
| 
613
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
5822
 | 
     my ($by, $count) = @_;  | 
| 
614
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
615
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
23
 | 
     die "missing string or regex to split by"  | 
| 
616
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         unless defined $by;  | 
| 
617
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
618
 | 
3
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
26
 | 
     die "count must be greater than 1 if present"  | 
| 
619
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if defined $count && $count <= 1;  | 
| 
620
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
621
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     if ($count) {  | 
| 
622
 | 
1
 | 
  
 50
  
 | 
 
 | 
  
1
  
 | 
 
 | 
19
 | 
         sub { defined $_[0] ? [ split $by, $_[0], $count ] : [] }  | 
| 
623
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     }  | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
625
 | 
1
 | 
  
 50
  
 | 
 
 | 
  
1
  
 | 
 
 | 
35
 | 
         sub { defined $_[0] ? [ split $by, $_[0] ] : [] }  | 
| 
626
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     }  | 
| 
627
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
629
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub trim {  | 
| 
630
 | 
5
 | 
 
 | 
  
100
  
 | 
  
5
  
 | 
  
1
  
 | 
14859
 | 
     my $only = shift // 'both';  | 
| 
631
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
43
 | 
     if ($only eq 'both') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {  | 
| 
633
 | 
2
 | 
  
 50
  
 | 
 
 | 
  
2
  
 | 
 
 | 
23
 | 
             return unless defined $_;  | 
| 
634
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
             s/\A\s+//;  | 
| 
635
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
             s/\s+\Z//r;  | 
| 
636
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
         };  | 
| 
637
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
638
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($only eq 'left') {  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {  | 
| 
640
 | 
1
 | 
  
 50
  
 | 
 
 | 
  
1
  
 | 
 
 | 
13
 | 
             return unless defined $_;  | 
| 
641
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
             s/\A\s+//r;  | 
| 
642
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
643
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     }  | 
| 
644
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($only eq 'right') {  | 
| 
645
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {  | 
| 
646
 | 
1
 | 
  
 50
  
 | 
 
 | 
  
1
  
 | 
 
 | 
11
 | 
             return unless defined $_;  | 
| 
647
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
             s/\s+\Z//r;  | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
649
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     }  | 
| 
650
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
651
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
         die qq[unknown trim option [$only], expected "both" or "left" or "right"];  | 
| 
652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
653
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
654
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
655
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =pod  | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =encoding UTF-8  | 
| 
660
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
662
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 FormValidator::Tiny - A tiny form validator  | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
665
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 VERSION  | 
| 
666
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 version 0.002  | 
| 
668
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
669
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
670
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
671
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     use FormValidator::Tiny qw( :validation :predicates :filtesr );  | 
| 
672
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     use Email::Valid;   # <-- for demonstration, not required  | 
| 
673
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     use Email::Address; # <-- for demonstration, not required  | 
| 
674
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     use Types::Standard qw( Int ); # <-- for demonstration, not required  | 
| 
675
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     validation_spec edit_user => [  | 
| 
677
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         login_name => [  | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             required => 1,  | 
| 
679
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             must     => limit_character_set('_', 'a-z', 'A-Z', '0-9'),  | 
| 
680
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             must     => length_in_range(5, 16),  | 
| 
681
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ],  | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         name => [  | 
| 
683
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             required => 1,  | 
| 
684
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             must     => length_in_range(1, 100),  | 
| 
685
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ],  | 
| 
686
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         age => [  | 
| 
687
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             optional => 1,  | 
| 
688
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             into     => '+',  | 
| 
689
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             must     => Int,  | 
| 
690
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             must     => number_in_range(13, '*'),  | 
| 
691
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ],  | 
| 
692
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         password => [  | 
| 
693
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             required => 1,  | 
| 
694
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             must     => length_in_range(8, 72),  | 
| 
695
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ],  | 
| 
696
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         confirm_password => [  | 
| 
697
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             required => 1,  | 
| 
698
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             must     => equal_to('password'),  | 
| 
699
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ],  | 
| 
700
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         email => [  | 
| 
701
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             required => 1,  | 
| 
702
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             must     => length_in_range(5, 250),  | 
| 
703
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             must     => sub { (  | 
| 
704
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             !!Email::Valid->address($_),  | 
| 
705
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             "That is not a well-formed email address."  | 
| 
706
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         ) },  | 
| 
707
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             into     => 'Email::Address',  | 
| 
708
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ],  | 
| 
709
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         groups => [  | 
| 
710
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             optional  => 1,  | 
| 
711
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             into      => split_by(' '),  | 
| 
712
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             into      => '[]',  | 
| 
713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             each_must => length_in_range(3, 20),  | 
| 
714
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             each_must => limit_character_set(  | 
| 
715
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                              ['_', 'a-z', 'A-Z'],  | 
| 
716
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                              ['_', '-', 'a-z', 'A-Z', '0-9'],  | 
| 
717
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          ),  | 
| 
718
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ],  | 
| 
719
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         tags   => [  | 
| 
720
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             optional   => 1,  | 
| 
721
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             into       => split_by(/\s*,\s*/),  | 
| 
722
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             each_into  => split_by(/\s\*:\s*/, 2),  | 
| 
723
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             into       => '{}',  | 
| 
724
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             key_must   => length_in_range(3, 20),  | 
| 
725
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             key_must   => qr/^(?:[A-Z][a-z0-9]*)(?:-[A-Z][a-z0-9]*)*)$/,  | 
| 
726
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             with_error => 'Tags keys must be of a form like "Favorite" or "Welcome-Message".',  | 
| 
727
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             value_must => length_in_range(1, 500),  | 
| 
728
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             value_must => limit_character_set('_', '-', 'a-z', 'A-Z', '0-9'),  | 
| 
729
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ],  | 
| 
730
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ];  | 
| 
731
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
732
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Somehow your web framework gets you a set of form parameters submitted by  | 
| 
733
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # POST or whatever. GO!  | 
| 
734
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $params = web_framework_params_method();  | 
| 
735
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ($parsed_params, $errors) = validate_form edit_user => $params;  | 
| 
736
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
737
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # You probably want better error handling  | 
| 
738
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ($errors) {  | 
| 
739
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         for my $field (keys %$errors) {  | 
| 
740
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             print "Error in $field: $_\n" for @{ $errors->{$field} };  | 
| 
741
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
742
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
743
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
744
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Form fields are valid, take action!  | 
| 
745
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
746
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         do_the_thing(%$parased_params);  | 
| 
747
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
748
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
749
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
750
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
751
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The API of this module is still under development and could change, but probably won't.  | 
| 
752
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
753
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 There are lots for form validators, but this one aims to be the one that just  | 
| 
754
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 one thing and does it well without involving anything else if it can. If you  | 
| 
755
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 just need a small form validator without installing all of CPAN, this will do  | 
| 
756
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 that. If you want to install all of CPAN and use a readable form validation spec  | 
| 
757
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 syntax, I hope this will do that too.  | 
| 
758
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
759
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This module requires Perl 5.18 or better as of this writing.  | 
| 
760
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
761
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 EXPORTS  | 
| 
762
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
763
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This module exports three sets of functions, each with their own export tag:  | 
| 
764
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
765
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
766
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
767
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item :validation  | 
| 
768
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
769
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is exported by default. It includes the two central functions provided by this interface, C and C.  | 
| 
770
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
771
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item :predicates  | 
| 
772
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
773
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This includes the built-in predicate helpers, used with C and C-like directives.  | 
| 
774
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
775
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
776
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
777
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item limit_character_set  | 
| 
778
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
779
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item length_in_range  | 
| 
780
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
781
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item equal_to  | 
| 
782
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
783
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item number_in_range  | 
| 
784
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
786
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
787
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item :filters  | 
| 
788
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
789
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This includes the build-in filter helpers, used with C and C-like directives.  | 
| 
790
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
791
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
792
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
793
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item split_by  | 
| 
794
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
795
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item trim  | 
| 
796
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
797
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
798
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
799
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
800
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
801
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 FUNCTIONS  | 
| 
802
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
803
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 validation_spec  | 
| 
804
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
805
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     validation_spec $spec_name => \@spec;  | 
| 
806
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
807
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This defines a validation specification. It associates a specification named  | 
| 
808
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C<$spec_name> with the current package. Any use of C within the  | 
| 
809
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 current package will use specifications named within the current package. The  | 
| 
810
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 following example would work fine as the "edit" spec defined in each controller  | 
| 
811
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 is in their respective package namespaces.  | 
| 
812
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
813
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     package MyApp::Controller::User;  | 
| 
814
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     validation_spec edit => [ ... ];  | 
| 
815
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub process_edits {  | 
| 
816
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my ($self, $c) = @_;  | 
| 
817
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my ($p, $e) = validate_form edit => $c->req->body_parameters;  | 
| 
818
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ...  | 
| 
819
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
820
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
821
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     package MyApp::Controller::Page;  | 
| 
822
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     validation_spec edit => [ ... ];  | 
| 
823
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub process_edits {  | 
| 
824
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my ($self, $c) = @_;  | 
| 
825
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my ($p, $e) = validate_form edit => $c->req->body_parameters;  | 
| 
826
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ...  | 
| 
827
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
828
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
829
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If you want to define them into a different package, name the package as part of  | 
| 
830
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the spec. Similarly, you can validate_form using a spec defined in a different  | 
| 
831
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package by naming the package when calling L:  | 
| 
832
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
833
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     package MyApp::Forms;  | 
| 
834
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     validation_spec MyApp::Controller::User::edit => [ ... ];  | 
| 
835
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
836
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     package MyApp::Controller::User;  | 
| 
837
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub process_groups {  | 
| 
838
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my ($self, $c) = @_;  | 
| 
839
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my ($p, $e) = validate_form MyApp::Controller::UserGroup::edit => $c->req->body_parameters;  | 
| 
840
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ...  | 
| 
841
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
842
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
843
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 You can also define your validation specification as lexical variables instead:  | 
| 
844
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
845
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $spec = validation_spec [ ... ];  | 
| 
846
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ($p, $e) = validate_form $spec, $c->req->body_parameters;  | 
| 
847
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
848
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 For information about how to craft a spec, see the L  | 
| 
849
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 section.  | 
| 
850
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
851
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 validate_form  | 
| 
852
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
853
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ($params, $errors) = validate_form $spec, $input_parameters;  | 
| 
854
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
855
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Compares the given parameters agains the named spec. The C<$input_parameters>  | 
| 
856
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 may be provided as either a hash or an array of alternating key-value pairs. All  | 
| 
857
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 keys and values must be provided as strings.  | 
| 
858
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
859
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The method returns two values. The first, C<$params>, is the parameters as far  | 
| 
860
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 as they have been validated so far. The second, C<$errors> is the errors that  | 
| 
861
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 have been detected.  | 
| 
862
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
863
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The C<$params> will be provided as a hash. The keys of this hash will match the  | 
| 
864
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 keys given in the spec. Some keys may be missing if the provided  | 
| 
865
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C<$input_parameters> did not contain values or those values are invalid.  | 
| 
866
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
867
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If there are no errors, the C<$errors> value will be set to C. With  | 
| 
868
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 errors, this will be hash of arrays. The keys of the hash will also match the  | 
| 
869
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 keys in the spec. Only fields with a validation error will be set. Each value  | 
| 
870
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 is an array of strings, with each string being an error message describing a  | 
| 
871
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 validation failure.  | 
| 
872
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
873
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 limit_character_set  | 
| 
874
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
875
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => limit_character_set(@sets)  | 
| 
876
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => limit_character_set(\@fc_sets, \@rc_sets);  | 
| 
877
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
878
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This returns a subroutine that limits the allowed characters for an input. In  | 
| 
879
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the first form, the character set limits are applied to all characters in the  | 
| 
880
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 value. In the second, the first array limits the characters permitted for the  | 
| 
881
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 first character and the second limits the characters permitted for the rest.  | 
| 
882
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
883
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Character sets may be provided as single letters (e.g., "_"), as named unicode  | 
| 
884
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 character properties wrapped in square brackets (e.g., "[Uppercase_Letter]"), or  | 
| 
885
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 as ranges connected by a hyphen (e.g., "a-z").  | 
| 
886
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
887
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 length_in_range  | 
| 
888
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
889
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => length_in_range('*', 10)  | 
| 
890
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => length_in_range(10, '*')  | 
| 
891
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => length_in_range(10, 100)  | 
| 
892
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
893
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This returns a subroutine for use with C declarations that asserts the  | 
| 
894
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 minimum and maximum string character length permitted for a value. Use an  | 
| 
895
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 asterisk to define no limit.  | 
| 
896
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
897
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 equal_to  | 
| 
898
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
899
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => equal_to('field')  | 
| 
900
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
901
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This returns a subroutine for use with C declarations that asserts that  | 
| 
902
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the value must be exactly equal to another field in the input.  | 
| 
903
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
904
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 number_in_range  | 
| 
905
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
906
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => number_in_range('*', 100)  | 
| 
907
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => number_in_range(100, '*')  | 
| 
908
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => number_in_range(100, 500)  | 
| 
909
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => number_in_range(exclusive => 100, exclusive => 500)  | 
| 
910
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
911
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Returns a predicate for must that requires the integer to be within the given range. The endpoints are inclusive by default. You can add the word "exclusive" before a value to make the comparison exclusive instead. Using a '*' indicates no limit at that end of the range.  | 
| 
912
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
913
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 split_by  | 
| 
914
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
915
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => split_by(' ')  | 
| 
916
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => split_by(qr/,\s*/)  | 
| 
917
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => split_by(' ', 2)  | 
| 
918
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => split_by(qr/,\s*/, 10)  | 
| 
919
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
920
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Returns an into filter that splits the string into an array. The arguments are  | 
| 
921
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 similar to those accepted by Perl's built-in C.  | 
| 
922
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
923
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 trim  | 
| 
924
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
925
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => trim  | 
| 
926
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => trim('left')  | 
| 
927
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => trim('right')  | 
| 
928
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
929
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Returns an into filter that trims whitespace from the input value. You can  | 
| 
930
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 provide an argument to trim only the left whitespace or the right whitespace.  | 
| 
931
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
932
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 VALIDATION SPECIFICATIONS  | 
| 
933
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
934
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The validation specification is an array reference. Each key names a field to  | 
| 
935
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 validate. The value is an array of processing declarations. Each processing  | 
| 
936
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 declaration is a key-value pair. The inputs will be processed in the order they  | 
| 
937
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 appear in the spec. The key names the type of processing. The value describes  | 
| 
938
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 arguments for the processing. The processing declarations will each be executed  | 
| 
939
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 in the order they appear. The same processor may be applied multiple times.  | 
| 
940
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
941
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Input Declarations  | 
| 
942
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
943
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Input declarations modify the initial value and must be given at the very top of  | 
| 
944
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the list of declarations for a field before all others.  | 
| 
945
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
946
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 from  | 
| 
947
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
948
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     from => 'input_parameter_name'  | 
| 
949
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
950
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Without this declaration, the validator pulls input from the parameter with the  | 
| 
951
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 same name as the key named in the validation spec. This input declaration  | 
| 
952
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 changes the key used for input.  | 
| 
953
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
954
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 as  | 
| 
955
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
956
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     multiple => 1  | 
| 
957
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
958
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The multiple input declaration tells the validator weather to interpret the  | 
| 
959
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 input parameter as a multiple input or not. Without this declaration or with it  | 
| 
960
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 set to 0, the validator will interpret multiple inputs as a single value,  | 
| 
961
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ignoring all but the last. With this declaration, it treat the input as multiple  | 
| 
962
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 items, even if there are 0 or 1.  | 
| 
963
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
964
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 trim  | 
| 
965
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
966
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     trim => 0  | 
| 
967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
968
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The default behavior of L is to trim whitespace from the beginning  | 
| 
969
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 and end of a value before processing. You can use the C declaration to  | 
| 
970
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 disable that.  | 
| 
971
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
972
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Filtering Declarations  | 
| 
973
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
974
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Filtering declarations inserted into the validation spec will replace the input  | 
| 
975
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 value with the newly filtered value at the point at which the declaration is  | 
| 
976
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 encountered.  | 
| 
977
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
978
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 into  | 
| 
979
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
980
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => '+'  | 
| 
981
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => '?'  | 
| 
982
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => '?+'  | 
| 
983
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => '?perl'  | 
| 
984
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => '?yes!no',  | 
| 
985
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => '[]'  | 
| 
986
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => '{}'  | 
| 
987
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => 'Package::Name'  | 
| 
988
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => sub { ... }  | 
| 
989
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     into => TypeObject  | 
| 
990
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
991
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is a filter declaration that transforms the input using the named coercion.  | 
| 
992
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
993
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
994
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
995
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Numeric  | 
| 
996
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
997
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Numeric coercion is performed using the '+' argument. This will convert the  | 
| 
998
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 value using Perl's built-in string-to-number conversion.  | 
| 
999
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1000
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Boolean  | 
| 
1001
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1002
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Boolean coercion is performed using the '?' argument. This will convert the  | 
| 
1003
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 value to boolean. It does not use Perl's normal mechanism, though. Instead, it  | 
| 
1004
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 converts the string to boolean based on string length alone. If the string is  | 
| 
1005
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 empty, it is false. If it is not empty it is true.  | 
| 
1006
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1007
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Boolean by Numeric  | 
| 
1008
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1009
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Boolean by Numeric coercion is performed using the '?+' argument. This will  | 
| 
1010
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 first convert the string input to a number and then the number will be collapsed  | 
| 
1011
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 to a boolean value such that 0 is false and any other value is true.  | 
| 
1012
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1013
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Boolean via Perl  | 
| 
1014
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1015
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Boolean via Perl coercion is performed using the '?perl' argument. This will  | 
| 
1016
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 convert to boolean using Perl's usual boolean logic.  | 
| 
1017
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1018
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Boolean via Enumeration  | 
| 
1019
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1020
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Boolean via Enumeration coercion is performed using an argument that starts with  | 
| 
1021
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 a question mark, '?', and contains an exclamation mark, '!'. The value between  | 
| 
1022
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the question mark and exclamation mark is the value that must be provided for a  | 
| 
1023
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 true value. The value provided between the exclamation mark and the end of  | 
| 
1024
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 string is the false value. Anything else will be treated as invalid and cause a  | 
| 
1025
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 validation error.  | 
| 
1026
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1027
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Array  | 
| 
1028
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1029
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Using a value of '[]' will make sure the value is treated as an array. This is a  | 
| 
1030
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 noop if the L declaration is set or if a L returns an array.  | 
| 
1031
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If the value is still a single, though, this will make sure the input value is  | 
| 
1032
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 placed inside an array references. This will also turn a hash value into an array.  | 
| 
1033
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1034
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Hash  | 
| 
1035
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1036
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Setting the declaration to '{}" will coerce the value to a hash. The even indexed  | 
| 
1037
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 values in the array will become keys and the odd indexed values in the array  | 
| 
1038
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 will become their respective values. If the value is not an array, it will turn  | 
| 
1039
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 a single value into a key/value pair with the key and the pair both being equal  | 
| 
1040
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 to the original value.  | 
| 
1041
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1042
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Package  | 
| 
1043
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1044
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 A package coercion happens when the string given is a package name. This assumes  | 
| 
1045
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 that passing the input value to the C constructor of the named package will  | 
| 
1046
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 do the right thing. If you need anything more complicated than that, you should  | 
| 
1047
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use a subroutine coercion.  | 
| 
1048
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1049
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Subroutine  | 
| 
1050
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1051
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 A subroutine coercion converts the value using the given subroutine. The current  | 
| 
1052
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 input value is passed as the single argument to the coercion (and also set as  | 
| 
1053
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the localized copy of C<$_>). The return value of the subroutine becomes the new  | 
| 
1054
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 input value.  | 
| 
1055
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Type::Tiny Coercion  | 
| 
1057
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1058
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If an object is passed that provides a C method. That method will be  | 
| 
1059
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 called on the current input value and the result will be used as the new input  | 
| 
1060
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 value.  | 
| 
1061
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1062
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
1063
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1064
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 each_into  | 
| 
1065
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1066
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_into => '+'  | 
| 
1067
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_into => '?'  | 
| 
1068
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_into => '?+'  | 
| 
1069
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_into => '?perl'  | 
| 
1070
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_into => '?yes!no',  | 
| 
1071
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_into => '[]'  | 
| 
1072
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_into => '{}'  | 
| 
1073
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_into => 'Package::Name'  | 
| 
1074
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_into => sub { ... }  | 
| 
1075
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_into => TypeObject  | 
| 
1076
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1077
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Performs the same coercion as L, but also works with arrays and hashes.  | 
| 
1078
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 It will apply the filter to a single value or to all elements of an array or to  | 
| 
1079
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 all keys and values of a hash.  | 
| 
1080
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1081
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 key_into  | 
| 
1082
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1083
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_into => '+'  | 
| 
1084
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_into => '?'  | 
| 
1085
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_into => '?+'  | 
| 
1086
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_into => '?perl'  | 
| 
1087
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_into => '?yes!no',  | 
| 
1088
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_into => '[]'  | 
| 
1089
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_into => '{}'  | 
| 
1090
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_into => 'Package::Name'  | 
| 
1091
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_into => sub { ... }  | 
| 
1092
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_into => TypeObject  | 
| 
1093
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1094
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Performs the same coercion as L, but also works with arrays and hashes.  | 
| 
1095
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 It will apply the filter to a single value or to all even index elements of an  | 
| 
1096
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 array or to all keys of a hash.  | 
| 
1097
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1098
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 value_into  | 
| 
1099
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_into => '+'  | 
| 
1101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_into => '?'  | 
| 
1102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_into => '?+'  | 
| 
1103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_into => '?perl'  | 
| 
1104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_into => '?yes!no',  | 
| 
1105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_into => '[]'  | 
| 
1106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_into => '{}'  | 
| 
1107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_into => 'Package::Name'  | 
| 
1108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_into => sub { ... }  | 
| 
1109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_into => TypeObject  | 
| 
1110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Performs the same coercion as L, but also works with arrays and hashes.  | 
| 
1112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 It will apply the filter to a single value or to all odd index elements of an  | 
| 
1113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 array or to all values of a hash.  | 
| 
1114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Validation Declarations  | 
| 
1116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 required  | 
| 
1118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 optional  | 
| 
1120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     required => 1  | 
| 
1122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     required => 0  | 
| 
1123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     optional => 1  | 
| 
1124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     optional => 0  | 
| 
1125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 It is strongly recommended that all fields add this declaratoi immediately after  | 
| 
1127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the input declarations, if any.  | 
| 
1128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 When required is set (or optional is set to 0), an initial validation check is  | 
| 
1130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 inserted that will fail if a value is not provided for this field. That value  | 
| 
1131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 must contain at least one character (after trimming, if trimming is not  | 
| 
1132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 disabled).  | 
| 
1133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 When optional is set (or required is set to 0), an initial validaiton check is  | 
| 
1135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 inserted that will shortcircuit the rest of the validation if no value is  | 
| 
1136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 provided.  | 
| 
1137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 must  | 
| 
1139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => qr/.../  | 
| 
1141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => sub { ... }  | 
| 
1142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     must => TypeObject  | 
| 
1143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This declaration states that the input given must match the described predicate.  | 
| 
1145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The module supports three kinds of predicates:  | 
| 
1146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
1148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Regular Expression  | 
| 
1150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This will match the given regular expression against the input. It is  | 
| 
1152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 recommended that the regular expression start with "^" or "\A" and end with "$"  | 
| 
1153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 or "\z" to force a total string match.  | 
| 
1154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The error message for these validates is not very good, so you probably want to  | 
| 
1156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 combine use of this kind of predicate with a following L  | 
| 
1157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 declaration.  | 
| 
1158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Subroutine  | 
| 
1160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ($valid, $message) = $code->($value, \%fields);  | 
| 
1162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The subroutine will be passed a two values. The first is the input to test  | 
| 
1164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 (which will also be set in the localalized copy of C<$_>). This second value  | 
| 
1165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 passed is rest of the input as processing currently stands.  | 
| 
1166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The return value must be a two element list.  | 
| 
1168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
1170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item 1.  | 
| 
1172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The first value returned is a boolean indicating whether the validation has  | 
| 
1174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 passed. A true value (like 1) means validation passes and there's no error. A  | 
| 
1175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 false value (like 0) means validation does not pass and an error has occured.  | 
| 
1176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 There is a third option, which is to return C. This indicates that  | 
| 
1178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 validaton should stop here. This is neither a success nor a failure. The value  | 
| 
1179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 processed so far will be ignored, but no error message is returned either. Any  | 
| 
1180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 further declarations for the field will be ignored as well.  | 
| 
1181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Returning C allows custom code to shortcircuit validation in exactly the  | 
| 
1183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 same was as setting C.  | 
| 
1184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item 2.  | 
| 
1186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The second value is the error message to use. It is acceptable to return an  | 
| 
1188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 error message even if the first value is a true or undefined value.  In that  | 
| 
1189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 case, the error message will be ignored.  | 
| 
1190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
1192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Type::Tiny Object  | 
| 
1194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The third option is to use a L-style type object. The  | 
| 
1196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L routine merely checks to see if it is an object that provides  | 
| 
1197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 a C method or a C method. If it provides a C  | 
| 
1198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 method, that method will be called and the boolean value returned will be  | 
| 
1199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 treated as the success or failure to validate. In this case, the error message  | 
| 
1200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 will be pulled from a call to C, if such a method is provided. In  | 
| 
1201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the C case, it will be called and a true value will be treated as  | 
| 
1202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the error message and a false value as validation success.  | 
| 
1203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 It is my experience that the error messages provided by L and  | 
| 
1205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 similar type systems are not friendly for use with end-uers. As such, it is  | 
| 
1206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 recommended that you provide a nicer error message with a following  | 
| 
1207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L declaration.  | 
| 
1208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
1210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 each_must  | 
| 
1212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_must => qr/.../  | 
| 
1214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_must => sub { ... }  | 
| 
1215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     each_must => TypeObject  | 
| 
1216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This declaration establishes validation rules just like L, but applies  | 
| 
1218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the test to every value. If the input is an array, that will apply to every  | 
| 
1219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 value. If the input is a hash, it will apply to every key and every value of the  | 
| 
1220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 hash. If it is a single scalar, it will apply to that single value.  | 
| 
1221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 key_must  | 
| 
1223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_must => qr/.../  | 
| 
1225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_must => sub { ... }  | 
| 
1226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     key_must => TypeObject  | 
| 
1227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is very similar to C, but only applies to keys. It will apply to  | 
| 
1229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 a single value, or to the even index values of an array, or to the keys of a  | 
| 
1230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 hash.  | 
| 
1231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 value_must  | 
| 
1233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_must => qr/.../  | 
| 
1235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_must => sub { ... }  | 
| 
1236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     value_must => TypeObject  | 
| 
1237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is very similar to C and complement of C. It will  | 
| 
1239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 apply to a single value, or to the odd index values of an array, or to the  | 
| 
1240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 values of a hash.  | 
| 
1241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 with_error  | 
| 
1243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     with_error => 'Error message.'  | 
| 
1245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     with_error => sub { ... }  | 
| 
1246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This defines the error message to associate with the previous C,  | 
| 
1248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C, C, C, C, C, and C  | 
| 
1249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 declaration. This will override any other associated message.  | 
| 
1250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If you would like to provide a different message based on the input, you may  | 
| 
1252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 provide a subroutine.  | 
| 
1253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SPECIAL VARIABLES  | 
| 
1255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The validation specifications are defined in each packages where  | 
| 
1257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L is called. This is done through a package variable named  | 
| 
1258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C<%FORM_VALIDATOR_TINY_SPECIFICATION>. If you really need to use that variable  | 
| 
1259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 for something else or if defining global package variables offends you, you can  | 
| 
1260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use the return value form of C, which will avoid creating this  | 
| 
1261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 variable.  | 
| 
1262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If you stick to the regular interface, however, this variable will be  | 
| 
1264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 established the first time C is called. The spec names are the  | 
| 
1265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 keys and the values have no documented definition. If you want to see what they  | 
| 
1266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 are, you must the read the code, but there's no guarantee that the internal  | 
| 
1267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 representation of this variable will stay the same in future releases.  | 
| 
1268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SEE ALSO  | 
| 
1270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L is very similar to this module in purpose and goals, but with  | 
| 
1272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 a different API.  | 
| 
1273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
1275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Andrew Sterling Hanenkamp   | 
| 
1277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT AND LICENSE  | 
| 
1279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This software is copyright (c) 2017 by Qubling Software LLC.  | 
| 
1281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is free software; you can redistribute it and/or modify it under  | 
| 
1283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the same terms as the Perl 5 programming language system itself.  | 
| 
1284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
1286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
1287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |