1 package Attribute::Params::Validate;
4 use warnings; # ok to use cause Attribute::Handlers needs 5.6.0+ as well
8 use Attribute::Handlers;
10 # this will all be re-exported
11 use Params::Validate qw(:all);
15 use vars qw($VERSION);
17 our @ISA = qw(Exporter);
19 my %tags = ( types => [ qw( SCALAR ARRAYREF HASHREF CODEREF GLOB GLOBREF SCALARREF HANDLE UNDEF OBJECT ) ],
22 our %EXPORT_TAGS = ( 'all' => [ qw( validation_options ), map { @{ $tags{$_} } } keys %tags ],
25 our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} }, 'validation_options' );
27 $VERSION = sprintf '%2d.%02d', q$Revision: 1.7 $ =~ /(\d+)\.(\d+)/;
30 sub UNIVERSAL::Validate : ATTR(CODE, INIT)
32 _wrap_sub('named', @_);
35 sub UNIVERSAL::ValidatePos : ATTR(CODE, INIT)
37 _wrap_sub('positional', @_);
42 my ($type, $package, $symbol, $referent, $attr, $params) = @_;
44 my @p = ref $params ? @{ $params } : $params;
46 my $subname = $package . '::' . *{$symbol}{NAME};
48 my %attributes = map { $_ => 1 } attributes::get($referent);
49 my $is_method = $attributes{method};
52 no warnings 'redefine';
55 # An unholy mixture of closure and eval. This is done so that
56 # the code to automatically create the relevant scalars from
57 # the hash of params can create the scalars in the proper
66 $code .= " my \$object = shift;\n" if $is_method;
71 $code .= " Params::Validate::validate(\@_, \$params);\n";
75 $code .= " Params::Validate::validate_pos(\@_, \@p);\n";
78 $code .= " unshift \@_, \$object if \$object;\n" if $is_method;
97 Attribute::Params::Validate - Validate method/function parameters using attributes
101 use Attribute::Params::Validate qw(:all);
103 # takes named params (hash or hashref)
104 # foo is mandatory, bar is optional
105 sub foo : Validate( foo => 1, bar => 0 )
110 # takes positional params
111 # first two are mandatory, third is optional
112 sub bar : ValidatePos( 1, 1, 0 )
117 # for some reason Perl insists that the entire attribute be on one line
118 sub foo2 : Validate( foo => { type => ARRAYREF }, bar => { can => [ 'print', 'flush', 'frobnicate' ] }, baz => { type => SCALAR, callbacks => { 'numbers only' => sub { shift() =~ /^\d+$/ }, 'less than 90' => sub { shift() < 90 } } } )
123 # note that this is marked as a method. This is very important!
124 sub baz : Validate( foo => { type => ARRAYREF }, bar => { isa => 'Frobnicator' } ) method
132 The Attribute::Params::Validate module allows you to validate method
133 or function call parameters just like Params::Validate does. However,
134 this module allows you to specify your validation spec as an
135 attribute, rather than by calling the C<validate> routine.
137 Please see Params::Validate for more information on how you can
138 specify what validation is performed.
142 This module exports everthing that Params::Validate does except for
143 the C<validate> and C<validate_pos> subroutines.
151 This attribute corresponse to the C<validate> subroutine in
156 This attribute corresponse to the C<validate_pos> subroutine in
163 If you are using this module to mark B<methods> for validation, as
164 opposed to subroutines, it is crucial that you mark these methods with
165 the C<:method> attribute, as well as the C<Validate> or C<ValidatePos>
168 If you do not do this, then the object or class used in the method
169 call will be passed to the validation routines, which is probably not
174 You B<must> put all the arguments to the C<Validate> or C<ValidatePos>
175 attribute on a single line, or Perl will complain.
183 Dave Rolsky, <autarch@urth.org>