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

NAME

Brick - Complex business rule data validation

SYNOPSIS

        use Brick;

        my $brick = Brick->new( {
                external_packages => [ qw(Foo::Validator Bar::Validator) ]
                } );

        my $profile = Brick::Profile->new( $brick,
                [ required  => sub { .... }    => $hash ],
                [ optional  => optional_fields => $hash ],

                [ inside    => in_number       => $hash ],

                [ outside   => ex_number       => $hash ],
                );

        my %input_from_app = (
                name => 'Joe Snuffy',
                ...
                );

        my $results = $brick->apply( $profile, \%%input_from_app );

DESCRIPTION

Class methods

Brick->new

Create a new Brick. Currently this doesn't do anything other than give you an object so you can call methods.

Future ideas? Maybe store several buckets or profiles?

Brick->error( MESSAGE )

Set the error message from the last things that happened.

Brick->error_str

Get the error message from the last things that happened.

Instance methods

create_bucket( PROFILE_ARRAYREF )
create_pool # DEPRECATED

This method creates a Brick::Bucket instance (or an instance in the package returned by $brick-bucket_class> ) based on the profile and returns the bucket instance. Along the way it affects the args hashref in each profile element to add the element name as the key profile_name and the actual coderef (not just the method name) as the key code. The closure generators are allowed to use those keys. For instance, __make_constraint, which is usually the top level closure, uses it to name the closure in the bucket.

If the profile doesn't pass lint test, this method croaks. You might want to safeguard that by calling lint first.

        my $bucket = do {
                if( my( $lint ) = $brick->lint( $profile ) )
                        {
                        $brick->create_bucket( $profile );
                        }
                else
                        {
                        Data::Dumper->Dump( [ $lint ], [qw(lint)] );
                        undef;
                        }
                };

From the profile it extracts the method name to create the closure for it based on its arguments. If the method item is already a code reference it uses it add is, but still adds it to the bucket. This could be handy for using closures from other classes, but I haven't investigated the consequences of that.

In scalar context this returns a new bucket instance. If the profile might be bad, use an eval to catch the croak:

        my $bucket = eval{ $brick->create_bucket( \@profile ) };

In list context, it returns the $bucket instance and an anonymous array reference with the stringified closures (which are also the keys in the bucket). The elements in the anonymous array correspond to the elements in the profile. This is handy in explain which needs to find the bucket entries for each profile elements. You probably won't need the second argument most of the time.

        my( $bucket, $refs ) = eval { $brick->create_bucket( \@profile ) };
init

Initialize the instance, or return it to a pristine state. Normally you don't have to do this because new does it for you, but if you subclass this you might want to override it.

add_validator_packages( PACKAGES )

Load external validator packages into the bucket. Each of these packages should export the functions they want to make available. add_validator_package requires each package and calls its import routine.

clone;

Based on the current instance, create another one just like it but not connected to it (in effect forking the instance). After the clone you can change new instance without affecting the old one. This is handy in explain, for instance, where I want a deep copy for a moment. At least I think I want a deep copy.

That's the idea. Right now this just returns the same instance. When not using a copy breaks, I'll fix that.

apply( PROFILE OBJECT, INPUT_DATA_HASHREF )

Apply the profile to the data in the input hash reference. The profile can either be a profile object or an array ref that apply() will use to create the profile object.

This returns a results object blessed into the class name returned by results_class(), which is Brick::Result by default. If you don't like that, you can override it in your own subclass.

bucket_class

The namespace where the constraint building blocks are defined. By default this is Brick::Bucket. If you don't like that, override this in a subclass. Things that need to work with the bucket class name, such as a factory method, will use the return value of this method.

This method also loads the right class, so if you override it, remember to load the class too!

result_class

The namespace that apply uses for its result object. By default this is Brick::Result. If you don't like that, override this in a subclass. Things that need to work with the result class name, such as a factory method, will use the return value of this method.

This method also loads the right class, so if you override it, remember to load the class too!

profile_class

The namespace for the profile object. By default this is Brick::Profile. If you don't like that, override this in a subclass. Things that need to work with the result class name, such as a factory method, will use the return value of this method.

This method also loads the right class, so if you override it, remember to load the class too!

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.