App-CELL
view release on metacpan or search on metacpan
lib/App/CELL/Guide.pm view on Meta::CPAN
up to the RT site administrator and contains only those parameters that
need to be different from the defaults. Parameter settings in
C<RT_SiteConfig.pm>, then, override the defaults set in C<RT_Config.pm>.
L<App::CELL> provides this same functionality in a drop-in Perl module,
with some subtle differences. While RT uses a syntax like this:
set( 'MY_PARAM', ...arguments...);
where C<...arguments...> is a list of scalar values (as with any Perl
subroutine), L<App::CELL> uses a slightly different format:
set( 'MY_PARAM', $scalar );
where C<$scalar> can be any scalar value, i.e. including references.
(Another difference is that L<App::CELL> provides both immutable site
parameters _and_ mutable C<meta> configuration parameters, whereas RT's
meta parameters are only used by RT itself.) For more information on
configuration, see L</Configuration in depth>.
=head2 Error handling
To facilitate error handling and make the application's source code easier
to read and understand, or at least mitigate its impenetrability, CELL
provides the L<App::CELL::Status> module, which enables functions in the
application to return status objects if desired.
Status objects have the following principal attributes: C<level>, C<code>,
C<args>, and C<payload>, which are given by the programmer when the status
object is constructed, as well as attributes like C<text>, C<lang>, and
C<caller>, which are derived by CELL. In addition to the attributes,
C<Status.pm> also provides some useful methods for processing status
objects.
In order to signify an error, subroutine C<foo_dis> could for example do
this:
return $CELL->status_err( code => 'Gidget displacement %s out of range',
args => [ $displacement ],
);
(Instead of having the error text in the C<code>, it could be placed in a
message file in the sitedir with a code like DISP_OUT_OF_RANGE.)
On success, C<foo_dis> could return an 'OK' status with the gidget
displacement value in the payload:
return $CELL->status_ok( payload => $displacement );
The calling function could check the return value like this:
my $status = foo_dis();
return $status if $status->not_ok;
my $displacement = $status->payload;
For details, see L<App::CELL::Status> and L<App::CELL::Message>.
CELL's error-handling logic is inspired by brian d foy's article "Return
error objects instead of throwing exceptions"
L<http://www.effectiveperlprogramming.com/2011/10/return-error-objects-instead-of-throwing-exceptions/>
=head2 Localization
This CELL component, called "Localization", gives the programmer a way to
encapsulate a "message" (in its simplest form, a string) within a message
object and then use that object in various ways.
So, provided the necessary message files have been loaded, the programmer
could do this:
my $message = $CELL->message( code => 'FOOBAR' );
print $message->text, '\n'; # message FOOBAR in the default language
print $message->text( lang => 'de' ) # same message, in German
Messages are loaded when CELL is initialized, from files in the site
configuration directory. Each file contains messages in a particular
language. For example, the file C<Dochazka_Message_en.conf> contains
messages relating to the Dochazka application, in the English language. To
provide the same messages in German, the file would be copied to
C<Dochazka_Message_de.conf> and translated.
Since message objects are used by L<App::CELL::Status>, it is natural for
the programmer to put error messages, warnings, etc. in message files and
refer to them by their codes.
C<App::CELL::Message> could also be extended to provide methods for
encrypting messages and/or converting them into various target formats
(JSON, HTML, Morse code, etc.).
For details, see </Localization in depth> and <App::CELL::Message>.
=head2 Logging
For logging, CELL uses L<Log::Any> and optionally extends it by adding
the caller's filename and line number to each message logged.
Message and status objects have 'log' methods, of course, and by default
all statuses (except 'OK') are logged upon creation.
Here's how to set up (and do) logging in the application:
use App::CELL::Log qw( $log );
$log->init( ident => 'AppFoo' );
$log->debug( "Three lines into AppFoo" );
L<App::CELL::Log> provides its own singleton, but since all method calls
are passed to L<Log::Any>, anyway, the L<App::CELL::Log> singleton behaves
just like its L<Log::Any> counterpart. This is useful, e.g., for testing
log messages:
use Log::Any::Test;
$log->contains_only_ok( "Three lines into AppFoo" );
To actually see your log messages, you have to do something like this:
use Log::Any::Adapter ( 'File', $ENV{'HOME'} . '/CELLtest.log' );
or, even simpler:
( run in 0.792 second using v1.01-cache-2.11-cpan-39bf76dae61 )