<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package Attribute::Params::Validate;
{
  $Attribute::Params::Validate::VERSION = '1.08';
}

use strict;
use warnings;

use attributes;

use Attribute::Handlers 0.79;

# this will all be re-exported
use Params::Validate qw(:all);

require Exporter;

our @ISA = qw(Exporter);

my %tags = (
    types =&gt; [
        qw( SCALAR ARRAYREF HASHREF CODEREF GLOB GLOBREF SCALARREF HANDLE UNDEF OBJECT )
    ],
);

our %EXPORT_TAGS = (
    'all' =&gt; [ qw( validation_options ), map { @{ $tags{$_} } } keys %tags ],
    %tags,
);
our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} }, 'validation_options' );


sub UNIVERSAL::Validate : ATTR(CODE, INIT) {
    _wrap_sub( 'named', @_ );
}

sub UNIVERSAL::ValidatePos : ATTR(CODE, INIT) {
    _wrap_sub( 'positional', @_ );
}

sub _wrap_sub {
    my ( $type, $package, $symbol, $referent, $attr, $params ) = @_;

    my @p = ref $params ? @{$params} : $params;

    my $subname = $package . '::' . *{$symbol}{NAME};

    my %attributes = map { $_ =&gt; 1 } attributes::get($referent);
    my $is_method = $attributes{method};

    {
        no warnings 'redefine';
        no strict 'refs';

        # An unholy mixture of closure and eval.  This is done so that
        # the code to automatically create the relevant scalars from
        # the hash of params can create the scalars in the proper
        # place lexically.

        my $code = &lt;&lt;"EOF";
sub
{
    package $package;
EOF

        $code .= "    my \$object = shift;\n" if $is_method;

        if ( $type eq 'named' ) {
            $params = {@p};
            $code .= "    Params::Validate::validate(\@_, \$params);\n";
        }
        else {
            $code .= "    Params::Validate::validate_pos(\@_, \@p);\n";
        }

        $code .= "    unshift \@_, \$object if \$object;\n" if $is_method;

        $code .= &lt;&lt;"EOF";
    \$referent-&gt;(\@_);
}
EOF

        my $sub = eval $code;
        die $@ if $@;

        *{$subname} = $sub;
    }
}

1;

# ABSTRACT: Define validation through subroutine attributes

__END__

=pod

=head1 NAME

Attribute::Params::Validate - Define validation through subroutine attributes

=head1 VERSION

version 1.08

=head1 SYNOPSIS

  use Attribute::Params::Validate qw(:all);

  # takes named params (hash or hashref)
  # foo is mandatory, bar is optional
  sub foo : Validate( foo =&gt; 1, bar =&gt; 0 )
  {
      ...
  }

  # takes positional params
  # first two are mandatory, third is optional
  sub bar : ValidatePos( 1, 1, 0 )
  {
      ...
  }

  # for some reason Perl insists that the entire attribute be on one line
  sub foo2 : Validate( foo =&gt; { type =&gt; ARRAYREF }, bar =&gt; { can =&gt; [ 'print', 'flush', 'frobnicate' ] }, baz =&gt; { type =&gt; SCALAR, callbacks =&gt; { 'numbers only' =&gt; sub { shift() =~ /^\d+$/ }, 'less than 90' =&gt; sub { shift() &lt; 90 } } } )
  {
      ...
  }

  # note that this is marked as a method.  This is very important!
  sub baz : Validate( foo =&gt; { type =&gt; ARRAYREF }, bar =&gt; { isa =&gt; 'Frobnicator' } ) method
  {
      ...
  }

=head1 DESCRIPTION

The Attribute::Params::Validate module allows you to validate method
or function call parameters just like Params::Validate does.  However,
this module allows you to specify your validation spec as an
attribute, rather than by calling the C&lt;validate&gt; routine.

Please see Params::Validate for more information on how you can
specify what validation is performed.

=head2 EXPORT

This module exports everything that Params::Validate does except for
the C&lt;validate&gt; and C&lt;validate_pos&gt; subroutines.

=head2 ATTRIBUTES

=over 4

=item * Validate

This attribute corresponds to the C&lt;validate&gt; subroutine in
Params::Validate.

=item * ValidatePos

This attribute corresponds to the C&lt;validate_pos&gt; subroutine in
Params::Validate.

=back

=head2 OO

If you are using this module to mark B&lt;methods&gt; for validation, as
opposed to subroutines, it is crucial that you mark these methods with
the C&lt;:method&gt; attribute, as well as the C&lt;Validate&gt; or C&lt;ValidatePos&gt;
attribute.

If you do not do this, then the object or class used in the method
call will be passed to the validation routines, which is probably not
what you want.

=head2 CAVEATS

You B&lt;must&gt; put all the arguments to the C&lt;Validate&gt; or C&lt;ValidatePos&gt;
attribute on a single line, or Perl will complain.

=head1 SEE ALSO

Params::Validate

=head1 AUTHOR

Dave Rolsky, &lt;autarch@urth.org&gt; and Ilya Martynov &lt;ilya@martynov.org&gt;

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2013 by Dave Rolsky and Ilya Martynov.

This is free software, licensed under:

  The Artistic License 2.0 (GPL Compatible)

=cut
</pre></body></html>