File Coverage

blib/lib/Attribute/Params/Validate.pm
Criterion Covered Total %
statement 64 65 98.4
branch 9 12 75.0
condition n/a
subroutine 14 14 100.0
pod 0 2 0.0
total 87 93 93.5


line stmt bran cond sub pod time code
1             package Attribute::Params::Validate;
2              
3 1     1   23248 use strict;
  1         2  
  1         26  
4 1     1   3 use warnings;
  1         2  
  1         36  
5              
6             our $VERSION = '1.21';
7              
8 1     1   787 use attributes;
  1         1210  
  1         5  
9              
10 1     1   597 use Attribute::Handlers 0.79;
  1         3121  
  1         8  
11 1     1   41 use Exporter 5.60 qw( import );
  1         13  
  1         33  
12              
13             # this will all be re-exported
14 1     1   599 use Params::Validate 1.21 qw(:all);
  1         6396  
  1         466  
15              
16             my %tags = (
17             types => [
18             qw( SCALAR ARRAYREF HASHREF CODEREF GLOB GLOBREF SCALARREF HANDLE UNDEF OBJECT )
19             ],
20             );
21              
22             our %EXPORT_TAGS = (
23             'all' => [ qw( validation_options ), map { @{ $tags{$_} } } keys %tags ],
24             %tags,
25             );
26             our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} }, 'validation_options' );
27              
28             sub UNIVERSAL::Validate : ATTR(CODE, INIT) {
29 3     3 0 5951 _wrap_sub( 'named', @_ );
30 1     1   10 }
  1         1  
  1         10  
31              
32             sub UNIVERSAL::ValidatePos : ATTR(CODE, INIT) {
33 2     2 0 1837 _wrap_sub( 'positional', @_ );
34 1     1   475 }
  1         2  
  1         5  
35              
36             ## no critic (Subroutines::ProhibitManyArgs))
37             sub _wrap_sub {
38 5     5   13 my ( $type, $package, $symbol, $referent, $attr, $params ) = @_;
39              
40 5 50       14 my @p = ref $params ? @{$params} : $params;
  5         13  
41              
42 5         10 my $subname = $package . '::' . *{$symbol}{NAME};
  5         16  
43              
44 5         18 my %attributes = map { $_ => 1 } attributes::get($referent);
  1         22  
45 5         93 my $is_method = $attributes{method};
46              
47             {
48             ## no critic (TestingAndDebugging::ProhibitNoStrict, TestingAndDebugging::ProhibitProlongedStrictureOverride)
49 1     1   384 no warnings 'redefine';
  1         3  
  1         71  
  5         7  
50 1     1   25 no strict 'refs';
  1         6  
  1         245  
51              
52             # An unholy mixture of closure and eval. This is done so that
53             # the code to automatically create the relevant scalars from
54             # the hash of params can create the scalars in the proper
55             # place lexically.
56              
57 5         12 my $code = <<"EOF";
58             sub
59             {
60             package $package;
61             EOF
62              
63 5 100       16 $code .= " my \$object = shift;\n" if $is_method;
64              
65 5 100       13 if ( $type eq 'named' ) {
66 3         10 $params = {@p};
67 3         6 $code .= " Params::Validate::validate(\@_, \$params);\n";
68             }
69             else {
70 2         5 $code .= " Params::Validate::validate_pos(\@_, \@p);\n";
71             }
72              
73 5 100       13 $code .= " unshift \@_, \$object if \$object;\n" if $is_method;
74              
75 5         7 $code .= <<"EOF";
76             \$referent->(\@_);
77             }
78             EOF
79              
80             ## no critic (BuiltinFunctions::ProhibitStringyEval)
81 5 50   2   638 my $sub = eval $code;
  2         2369  
  1         47  
  1         1312  
  0         0  
  2         2190  
  1         7  
  1         999  
  1         7  
  1         1208  
  1         20  
  1         9  
  1         6  
82 5 50       18 die $@ if $@;
83              
84 5         10 *{$subname} = $sub;
  5         54  
85             }
86             }
87             ## use critic
88              
89             1;
90              
91             # ABSTRACT: Define validation through subroutine attributes
92              
93             __END__