The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Brick::Profile - the validation profile for Brick

SYNOPSIS

DESCRIPTION

This class turns a profile description into a ready-to-use profile object that has created all of the code it needs to validate input. In Brick parlance, it creates the bucket and the bricks that need to go into the bucket based on the validation description.

Validation profile

The validation profile is an array of arrays. Each item in the array specifies three things: a label for that item, the name of the method to run to validate the item, and optional arguments to pass to the the method.

For instance, here's a simple validation description to check if a user is registered with the system. This profile has one item:

        @profile = (
                [ username => is_registered => { field => form_name } ],
                );

The label for the item is username. When Brick reports the results of the validation, the label username will be attached to the result for this part of the validation.

The method that validates this item is is_registered. When you create the profile, Brick will look for that method in either it's included methods in Brick::Bucket classes or the ones you load with Brick::add_validator_packages. This method is called a "brick" because it's one piece of the entire validation.

Additionally, Brick will pass the optional arguments, in this case { field = form_name }>, to is_registered. A brick merely creates a closure that will run later, so the optional arguments are for the initialization of that closure. The validation doesn't happen until you apply it.

Class methods

new( BRICK, ARRAY_OF_ARRAYS )

Create a new profile object tied to the Brick object.

brick_class()

Return the class name to use to access class methods (such as bucket_class) in the Brick namespace. If you want to provide an alternate Brick class for your profile, override this method.

Instance methods

lint( PROFILE_ARRAYREF );

Examine the profile and complain about irregularities in format. This only checks the format; it does not try to determine if the profile works or makes sense. It returns a hash whose key is the index of the profile element and whose value is an anonymous hash to indicate what had the error:

        format  -   the element is an arrayref
        name    -   the name is a scalar
        method  -   is a code ref or can be found in the package
                                        $brick->bucket_class returns
        args    -   the last element is a hash reference

If the profile is not an array reference, lint immediately returns undef or the empty list. In scalar context, lint returns 0 for format success and the number of errors (so true) for format failures. If there is a format error (e.g. an element is not an array ref), it immediately returns the number of errors up to that point.

        my $lint = $brick->profile_class->lint( \@profile );

        print do {
                if( not defined $lint ) { "Profile must be an array ref\n" }
                elsif( $lint )          { "Did not validate, had $lint problems" }
                else                    { "Woo hoo! Everything's good!" }
                };

In list context, it returns a hash (a list of one element). The result will look something like this hash, which has keys for the elements that lint thinks are bad, and the values are anonymous hashes with keys for the parts that failed:

        %lint = (
                1 => {
                        method => "Could not find method foo in package",
                        },
                4 => {
                        args => "Arguments should be a hash ref, but it was a scalar",
                        }
                );

If you are using AUTOLOAD to generate some of the methods at runtime (i.e. after lint has a chance to check for it), use a can method to let lint know that it will be available later.

TO DO:

Errors for duplicate names?

explain()

Turn the profile into a textual description without applying it to any data. This does not add the profile to instance and it does not add the constraints to the bucket.

If everything goes right, this returns a single string that represents the profile.

If the profile does not pass the lint test, this returns undef or the empty list.

If you want to do something with a datastructure, you probably want to write a different method very similar to this instead of trying to parse the output.

Future notes: maybe this is just really a dispatcher to things that do it in different ways (text output, hash output).

get_bucket
set_bucket
get_coderefs
set_coderefs
get_array
set_array

Using a different class

If you don't want to use this class, you can specify a different class to use in your Brick subclass. Override the Brick::profile_class() method to specify the name of the class that you want to use instead. That might be a subclass or an unrelated class. Your class will need to use the same interface even though it does things differently.

TO DO

TBA

SEE ALSO

Brick::Tutorial, Brick::UserGuide

SOURCE AVAILABILITY

This source is in Github:

        https://github.com/briandfoy/brick

AUTHOR

brian d foy, <bdfoy@cpan.org>

COPYRIGHT

Copyright © 2007-2022, brian d foy <bdfoy@cpan.org>. All rights reserved.

You may redistribute this under the terms of the Artistic License 2.0.