NAME
Class::AbstractLogic - Handling Logic Abstractions
SYNOPSIS
# the logic class definition
package My::Logic::Foo;
use Class::AbstractLogic-base;
# a logic action
action 'add',
needs [qw(a b)],
verify { a => sub { /^\d+$/ }, b => sub { /^\d+$/ } },
sub { $_{a} + $_{b} };
1;
...
# logic module manager creation
use Class::AbstractLogic;
my $calm = Class::AbstractLogic::Manager->new;
# loading a logic class
$calm->load_logic(Foo => 'My::Logic::Foo');
# requesting a result from a logic method
my $result = $calm->logic('Foo')->add(a => 11, b => 12);
# $result will be false if an exception was caught
if ($result) {
print 'result was ' . $result->value . "\n";
}
else {
print 'exception raised: ' . $result->key . "\n";
print 'error message: ' . $result->error . "\n";
}
DESCRIPTION
This module provides a small framework to abstract logics. It was mostly thought to have a place for isolated business-logic that does neither fit in the MVC concepts controllers nor its models.
Logic Modules
package FooLogic;
use warnings;
use strict;
use Class::AbstractLogic-base;
# ... action definitions ...
1;
You can create a new logic module easily. By use
ing Class::AbstractLogic
with the postfix -base
you request the installation of action helpers as well as the Class::AbstractLogic::Base class into this modules @ISA
.
Action Definitions
...
action 'foo', needs [qw(field1 field2)],
verify { field1 => sub { ... }, ... },
sub { do_stuff_with($_{field1}) };
...
The installed helpers are named action
, needs
and verify
. The first defines the actions name. needs
accepts either an arrayref with a list of, or a scalar with a single field name that have to be specified in the arguments to this action. The verify
hash reference takes a code reference for each key representing an argument name. The code ref gets the value passed in @_
and as $_
. If it returns a false value, an error is thrown.
action
just looks for a code reference in the stream of its arguments to determine which is the subroutine that actually represents the action. The arguments passed with the call are available in @_
after the first value representing the current logical module object, and also come in the global hash %_
for easier and more readable access. Via &_
you can access other logical classes:
action 'foo',
sub { my $res = _('Bar')->bar(baz => 23); ... }
Note however, that the return values of calls to other logic methods will return Class::AbstractLogic::Result
objects which you have to deal with. If your action returns a result object, however, it will not be rewrapped in another result, but just returned itself.
Through the logical module object you have access to the config
and error
methods.
Logic Modules and the Manager, General Usage
my $calm = Class::AbstractLogic::Manager->new(
config => { Foo => { foobar => 23 }} );
This creates a new logic module manager. The configuration is logic module specific. In the above example, a logic module registered under Foo
will have { foobar => 23 }
as its config value.
$calm->load_logic(Foo => 'FooLogicClass');
This loads the class FooLogicClass
and registers it in themanager under the name Foo
.
my $result = $calm->logic('Foo')->foo(field1 => 12, field2 => 13);
This calls the action foo
with the arguments field1
and field2
on the logic module registered under the name Foo
.
The Result
if ($result) { print "ok\n" } else { print "not ok\n" }
The boolean value of the result object will be false if an exception was thrown. If the call succeeded, it will evaluate to true and you can access the value via the result
method or its value
alias.
Logic Exceptions
To provide a facility to handle errors and other exception like things, C:AL
has a built-in exception handling facility. Inside of your actions you can just throw an exception, which will propagate up to the place the current action was called from.
action 'foo',
sub { my $self = shift;
$self->throw( foobar => 'Extensive Error Message' );
};
...
my $result = $calm->logic('WithDyingFoo')->foo(bar => 23);
In the above example, the $result
will evaluate to false. You can access its error message through the error
method, and its error key (the first argument you specified, it's for easier flow handling with exceptions) through the key
method. If you need, you can also get to the original exception object through exception
.
METHODS
import(@args)
Handles helper installations in your Logic Modules.
import_helpers($target)
Internal method that installs the action
, needs
and verify
helpers in $target
.
_handle_action(@args)
Helper Method, creates a new action in a Logic Class.
_handle_needs($spec)
Helper Method, checks and flags the needs
specification.
_handle_verify($spec)
Helper Method, checks and flags the verify
specification.
AUTHOR
Robert 'phaylon' Sedlacek <phaylon@dunkelheit.at>
LICENSE AND COPYRIGHT
This program is free software, you can redistribute it and/or modify it under the same terms as Perl itself.