MooX::Params::CompiledValidators - A Moo::Role for using Params::ValidationCompiler.
use Moo; use Types::Standard qw( Str ); with 'MooX::Params::CompiledValidators'; sub any_sub { my $self = shift; my $arguments = $self->validate_parameters( { $self->parameter(customer_id => $self->Required), }, { @_ } ); ... } # Implement a local version of the ValidationTemplates sub ValidationTemplates { return { customer_id => { type => Str }, }; }
This role uses Params::ValidationCompiler to create parameter validators on a per method basis that can be used in the methods of your Moo or Moose projects.
The objective is to create a single set of validation criteria - ideally in a seperate role that can be used along side of this role - that can be used to consistently validate parameters throughout your application.
The validators created by Params::ValidationCompiler are cached after they are created the first time, so they will only be created once.
A validation-template is a structure (HashRef) that Params::ValidationCompiler::validation_for() uses to validate the parameter and basically contains three keys:
Params::ValidationCompiler::validation_for()
Params::ValidationCompiler supports a number of type systems, see their documentation.
Params::ValidationCompiler
Define a default value for this parameter, either a simple scalar or a code-ref that returns a more complex value.
By default false, required parameters are preferred by Params::ValidationCompiler
ValidationTemplates()
The objective of this module (Role) is to standardise parameter validation by defining a single set of Validation Templates for all the parameters in a project. This is why the MooX::Params::CompiledValidators role requires a ValidationTemplates method in its consuming class. The ValidationTemplates method is needed for the parameter() method that is also supplied by this role.
MooX::Params::CompiledValidators
requires
ValidationTemplates
parameter()
This could be as simple as:
package MyTemplates; use Moo::Role; use Types::Standard qw(Str); sub ValidationTemplates { return { customer_id => { type => Str }, username => { type => Str }, }; }
Required()
validation_for() uses the attribute optional so this returns 0
validation_for()
optional
0
Optional
validation_for() uses the attribute optional so this returns 1
1
validate_parameters()
Returns a (locked) hashref with validated parameters or die()s trying...
die()
Given:
use Moo; with 'MooX::Params::CompiledValidators'; sub show_user_info { my $self = shift; my $args = $self->validate_parameters( { customer_id => { type => Str, optional => 0 }, username => { type => Str, optional => 0 }, }, { @_ } ); return { customer => $args->{customer_id}, username => $args->{username}, }; }
One would call this as:
my $user_info = $instance->show_user_info( customer_id => 'Blah42', username => 'blah42', );
Positional:
$validation_templates
A hashref with the parameter-names as keys and the "Validation-Templates" as values.
$values
A hashref with the actual parameter-name/value pairs that need to be validated.
A locked hashref.
A list that can be coerced into a hash.
Anything Params::ValidationCompiler will throw for invalid values.
validate_positional_parameters()
Like $instance->validate_parameters(), but now the pairs of name, validation-template are passed in an arrayref, that is split into lists of the names and templates. The parameters passed -as an array- will be validated against the templates-list, and the validated results are combined back into a hash with name/value pairs. This makes the programming interface almost the same for both named-parameters and positional-parameters.
$instance->validate_parameters()
use Moo; with 'MooX::Params::CompiledValidators'; sub show_user_info { my $self = shift; my $args = $self->validate_positional_parameters( [ customer_id => { type => Str, optional => 0 }, username => { type => Str, optional => 0 }, ], \@_ ); return { customer => $args->{customer_id}, username => $args->{username}, }; }
my $user_info = $instance->show_user_info('Blah42', 'blah42');
A arrayref with pairs of parameter-names and "validation templates".
A arrayref with the actual values that need to be validated.
Returns a parameter_name, validation_template pair that can be used in the parameters argument hashref for Params::ValidationCompiler::validadion_for()
parameter_name
validation_template
parameters
Params::ValidationCompiler::validadion_for()
$name
The name of this parameter (it must be a kind of identifier: m{^\w+$})
m{^\w+$}
$required
One of $class->Required or $class->Optional but will default to $class->Required.
$class->Required
$class->Optional
$extra
This optional HashRef can contain the fields supported by the params parameter of validation_for(), even overriding the ones set by the $class->ValidationTemplates() for this $name - although optional is set by the previous parameter in this sub.
params
$class->ValidationTemplates()
This parameter is mostly used for the extra feature to pass a lexically scoped variable via store.
A list of $parameter_name and $validation_template.
$parameter_name
$validation_template
(this_parm => { optional => 0, type => Str, store => \my $this_param })
Whenever $self->parameter() is called with a parameter-name that doesn't resolve to a template in the ValidationTemplates() hash, a default "empty" template is produced. This will mean that there will be no validation on that value, although one could pass one as the third parameter:
$self->parameter()
use Moo; use Types::Standard qw( StrMatch ); with qw( MyTemplates MooX::Params::CompiledValidators ); sub show_user_info { my $self = shift; my $args = $self->validate_parameters( { $self->parameter(customer_id => $self->Required), $self->parameter( email => $self->Required, { type => StrMatch[ qr{^ [-.\w]+ @ [-.\w]+ $}x ] }, ), }, { @_ } ); return { customer => $args->{customer_id}, email => $args->{email}, }; }
store
Both validate_parameters() and validate_positional_parameters support the extra store attribute in a validation template that should be a scalar-reference where we store the value after successful validation.
validate_positional_parameters
One can pick and mix with validation templates:
use Moo; use Types::Standard qw( StrMatch ); with qw( MyTemplates MooX::Params::CompiledValidators ); sub show_user_info { my $self = shift; $self->validate_parameters( { $self->parameter(customer_id => $self->Required, {store => \my $customer_id), email => { type => StrMatch[ qr{^ [-.\w]+ @ [-.\w]+ $}x ], optional => 0, store => \my $email }, }, { @_ } ); return { customer => $customer_id, email => $email, }; }
my $user_info = $instance->show_user_info( customer_id => 'Blah42', email => 'blah42@some.tld', );
One could argue that using (lexical) variables -instead of addressing keys of a locked hash- triggers the error caused by a typo at compile-time rather than at run-time.
NOTE: In order to keep the scope of the variable, where the value is stored, limited, the store attribute should only be used from the per method override option extra for $self->parameter().
extra
© MMXXI - Abe Timmerman <abeltje@cpan.org>
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
To install MooX::Params::CompiledValidators, copy and paste the appropriate command in to your terminal.
cpanm
cpanm MooX::Params::CompiledValidators
CPAN shell
perl -MCPAN -e shell install MooX::Params::CompiledValidators
For more information on module installation, please visit the detailed CPAN module installation guide.