NAME
App::Kit - A Lazy Façade to simplify your code/life
VERSION
This document describes App::Kit version 0.63
SYNOPSIS
Use directly in your code:
## no critic (RequireUseStrict) - App::Kit does strict and warnings
use App::Kit;
my $app = App::Kit->multiton; # now your script and all the modules that make it up have access to the same logging, localization, and a host of other fetaures without loading anything for them and not requiring special voo doo to load/initialize.
Or roll your own to use instead:
package My::App;
## no critic (RequireUseStrict) - Moo does strict and warnings
use Moo;
extends 'App::Kit';
with '…'; # add a new role
has 'newthing' => ( … ); # add a new attr
has '+app_kit_thingy' => ( … ); # customize an existing role/attr/method
sub newmeth { … } # add a new method
…
DESCRIPTION
A Lazy Façade to simplify your code/life. How?
Ever see this sort of thing in a growing code base:
package My::Thing;
use strict;
use warnings;
use My::Logger;
my $logger;
sub foo {
my ($x, $y, $z) = @_;
if ($x) {
$logger ||= MyLogger->new;
$logger->info("X is truly $x");
}
…
}
but if that module (or script) had access to your App::Kit object:
package My::Thing;
## no critic (RequireUseStrict) - MyApp does strict and warnings
use MyApp;
my $app = MyApp->multiton; # ok to do this here because it is really really cheap
sub foo {
my ($x, $y, $z) = @_;
if ($x) {
$app->log->info("X is truly $x");
}
…
}
Multiply that by hundreds of scripts and modules and vars and tests and wrappers. ick
Some specifics:
one class/one object to consistently and simply manage some of the complexities of a large code base
Don’t pass around globals, a zillion args, have a bunch of was-this-loaded, do-we-have-that, etc.
Just create the object and use it everywhere. Done, it all works the same with no boiler plate required besides Foo->instance and use it when you need.
only what you need, when you need it
Only load and instantiate the things your code actually does, with no effort.
Reuse them throughout the code base, again, with no effort!
use default objects or set your own
The defaults will work and as your project expands you can customize if needed without needing to refactor your code.
For example, once you sprint the localization setup, you can change your class’s locale() to use your object.
easy mocking (for your tests!)
By default the lazy façade methods are readonly (technically 'rwp' so the class can fiddle with them internally if it needs to).
You can change make them readwrite via either of 2 mechanisms before the class is built via use().
Either:
use App::Kit::Util::RW; # must be loaded before App::Kit is use()d
use App::Kit;
or
BEGIN { $ENV{'App-Kit-Util-RW'} = 1; }; # must be set before App::Kit is use()d
use App::Kit;
then:
$app->log($test_logger); # e.g. say $test_logger stores what level and msg are called/given
… something that should call $app->log->info('This is a terrible info msg.') …
… test that $test_logger saw the expected levels and msgs …
The former might be desirable if you want to keep ENV clean, the latter for when you want to do/skip certain tests based on if it is true or not:
App-Kit-Util-RW=1 prove -w t
INTERFACE
auto imports
strict and warnings enabled automatically
try/catch/finally imported automatically (unless you say not to)
Try::Tiny is enabled automatically unless you pass import() “-no-try” flag (Yoda was right: there *is* -no-try!):
use App::Kit '-no-try';
same goes for your App::Kit based object:
use My::App '-no-try';
constructors: multiton support
new()
Since the idea of this class is to share the objects it makes more sense to use multiton()/instance() in your code.
Returns a new object every time. Takes no arguments currently.
multiton()
Returns the same object on subsequent calls using the same arguments. Since, there are currently no arguments it is essentially a singleton.
See Role::Multiton for more details.
instance()
Alias to multiton(). If you ever plan on modifying the constructor to another type (weirdo) you may want to use this in your code instead of multiton().
See Role::Multiton for more details.
Lazy façade methods
Each method returns a lazy loaded/instantiated object that implements the actual functionality.
$app->log
Lazy façade to a logging object via App::Kit::Role::Log.
$app->locale
Lazy façade to a maketext() object via App::Kit::Role::Locale.
Has all the methods any Locale::Maketext::Utils based object would have.
Localize your code now without needing an entire subsystem in place just yet!
$app->detect
Lazy façade to a context detection object via App::Kit::Role::Detect.
$app->ctype
Lazy façade to a ctype utility object via App::Kit::Role::CType.
$app->str
Lazy façade to a string utility object via App::Kit::Role::Str.
$app->ns
Lazy façade to a name space utility object via App::Kit::Role::NS.
$app->http
Lazy façade to an HTTP client object via App::Kit::Role::HTTP.
$app->fs
Lazy façade to a file system utility object via App::Kit::Role::FS.
$app->db
Lazy façade to a database utility object via App::Kit::Role::DB.
$app->ex
Lazy façade to a system execution utility object via App::Kit::Role::Ex.
DIAGNOSTICS
Throws no warnings or errors of its own.
All errors or warnings would come from perl, Moo, or the façade object in question.
CONFIGURATION AND ENVIRONMENT
App::Kit requires no configuration files or environment variables.
If, however, the façade object in question does it will be documented specifically under it.
DEPENDENCIES
Moo et al.
If you don't pass in -no-try: Try::Tiny and Import::Into
Other modules would be documented above under each façade object that brings them in.
INCOMPATIBILITIES
None reported.
BUGS AND LIMITATIONS
No bugs have been reported.
Please report any bugs or feature requests to bug-app-kit@rt.cpan.org
, or through the web interface at http://rt.cpan.org.
TODO
- 1. More Lazy façade methods
-
App::Kit::Role::Crypt
# $app->crypt->encrypt($str, $cipher) $app->xcrypt->decrypt($str, $cipher) ->rand_data
App::Kit::Role::Cache
# e.g Chi if it drops a few pounds by eating less Moose
App::Kit::Role::In
# i.e. HTTP or ARGV == $app->in->param('name')
App::Kit::Role::Out
# e.g.TT/classes/ANSI
return obj/exception
- 2. Encapsulate tests that commonly do:
-
Class::Unload->unload('…'); ok(!exists $INC{'….pm'}, 'Sanity: … not loaded before'); is $app->?->…, '…', '?() …' ok(exists $INC{'….pm'}, '… lazy loaded on initial ?()');
- 3. easy to implement modes
-
for example:
root_safe: make certain methods die if called by root under some circumstance
(e.g. root calling file system utilities on paths owned by a user, forces them to drop privileges)
owner_mode: process is running as owner of script
chdir_safe: make chdir fatal
AUTHOR
Daniel Muey <http://drmuey.com/cpan_contact.pl>
LICENCE AND COPYRIGHT
Copyright (c) 2013, Daniel Muey <http://drmuey.com/cpan_contact.pl>
. All rights reserved.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic.
DISCLAIMER OF WARRANTY
BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.