Class::Validating - Provide Subclass-able Validation Mechanism
package MyClass; use Class::Validating; __PACKAGE__->set_pv_spec(foo => { type => Params::Validate::HASHREF() }); sub foo { my $self = shift; # validate @_ according to set_pv_spec() above my %args = $self->validate_args(@_); ... } package MySubClass; use base qw(MyClass); __PACKAGE__->set_pv_spec(%newspec); sub foo { my $self = shift; # now validate @_ according to %newspec, not MyClass' spec for foo my %args = $self->validate_args(@_); # you can call the super class' method as well, and it will # use the correct spec $self->SUPER::validate_args(...); }
Params::Validate is a great parameter validation tool, but because a lot of the code that utilises Params::Validate tend to be written with a lexical validation spec (like the code below) it was either hard or tedious to extend the class that uses Params::Validate.
A typical code that uses Params::Validate might look like this:
package MyClass; use strict; use Params::Validate qw(validate SCALAR HASHREF); my %FooValidate = ( arg1 => { type => SCALAR }, arg2 => { type => HASHREF } ); sub foo { my $self = shift; my %args = validate(@_, \%FooValidate); .... }
This code unfortunately doesn't allow too much flexibility for someone trying to write a subclass, because %FooValidate is a lexical variable and is not visible in the subclass.
This module tries to solve this problem by creating a data slot via Class::Data::Inheritable.
Using Class::Validating, above example now look like this:
package MyClass; use strict; use Class::Validating; __PACKAGE__->set_pv_spec(foo => { arg1 => {type => SCALAR}, arg2 => {type => HASHREF} }); sub foo { my $self = shift; my %args = $self->validate_args(@_); ... }
In your subclass, you will be able to change the validation behavior by calling set_pv_spec():
package MySubclass; use strict; use base qw(MyClass); __PACKAGE__->set_pv_spec(foo => { arg1 => {type => SCALAR}, arg2 => {type => HASHREF}, arg3 => {type => ARRAYREF} }); sub foo { my $self = shift; my %args = $self->validate_args(@_); .... # you can safely call the parent's foo() method, and expect it # to validate using the parent's validation spec: $self->SUPER::foo(@args); }
@args = $self->validate_args(\@_); %opts = (called => "foo bar"); @args = $self->validate_args(\@_, \%opts);
Validates @args, using the validation spec that the current subroutine name points to. The validation spec must be defined via set_pv_spec() prior to calling this method. If no spec matching the method name is found, an exception will be thrown.
%opts may contain extra arguments to Params::Validate::validate_with(), such as 'allow_extra', 'called', etc. Note that if you give the "spec" argument to %opts, it WILL override whatever validation spec you defined in set_pv_spec(). See Params::Validate for more details
Set the Params::Validate spec for a subroutine. The subroutine name must be given as the unqualified name (no module prefixes).
set_pv_spec() can take either a hashref or arrayref as its second argument.
$class->set_pv_spec(subname => \%spec); $class->set_pv_spec(subname => \@spec);
The difference is that a hashref implicitly means the subroutine expects named parameters, and arrayref means the subroutine expects positional parameters (i.e., the difference between P::V::validate() and P::V::validate_pos())
Returns the validation spec for the given subroutine name. The subroutine name is passed as a unqualified name (i.e., no package prefixes)
$spec = $class->get_pv_spec($subname)
Params::Validate
Daisuke Maki <dmaki@cpan.org>
To install Class::Validating, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Class::Validating
CPAN shell
perl -MCPAN -e shell install Class::Validating
For more information on module installation, please visit the detailed CPAN module installation guide.