[Catalyst] Random thoughts on helper class generation
neil.lunn
neil at mylunn.id.au
Sat Jan 25 02:40:04 GMT 2014
On 25/01/2014 10:58 AM, neil.lunn wrote:
> Hi all,
>
> Was just thinking through setting up various project minting files and
> got to looking at the default Catalyst app layout from the helper.
> Specifically I wondered how much the defaults were just being cargo
> culted, and specifically addressing my dislike for overuse of inline
> __PACKAGE__ calls when we have Moose and BUILD available. So random
> musings below:
>
Oops. Big fail. Forgot the most important bit. See edit
> Here's a sensible base class for the App context:
>
> package Catalyst::BaseClass;
> use Moose;
> use namespace::autoclean;
>
> use Catalyst::Runtime 5.80;
> use Catalyst qw/ PluginLoader /; # Should be all we need
>
> extends 'Catalyst';
>
> our $VERSION = '0.01';
>
> sub hook_config {
> my $self = shift;
> my $class = ref($self);
>
> # Set some basic defaults
> return {
> name => $class,
> enable_catalyst_header => 1, # Send X-Catalyst header
> };
> }
>
> sub hook_logger {
> # Do nothing by default. Setup will take care of it.
> }
>
> sub BUILD {
> my $self = shift;
> my $class = ref($self);
>
unless ( $self->setup_finished ) {
> # Setup Config
> $self->config(
> %{ $self->hook_config }
> );
>
> # Place a hook to hang a logger on before setup is called
> $self->hook_logger();
>
> $class->setup();
}
>
> }
>
> As you can see by the "hook" methods, this was "take 2" where I was
> abstracting my personal "cause" from the general base class. By
> placing the hooks in you can abstract in your application, as in:
>
> package YourApp::Web;
> use Moose;
> use namespace::autoclean;
>
> extends 'Catalyst::BaseClass';
>
> our $VERSION = '0.01';
>
> our $load_class = \&Plack::Util::load_class;
>
> around 'hook_config' => sub {
> my $orig = shift;
> my $self = shift;
> my $class = ref($self);
> my $basename = $class;
> $basename =~ s/::.+//g;
>
> use Hash::Merge qw/merge/;
>
> # Setup Config
> my $configclass = $load_class->( "${basename}::Config" );
> return merge( $self->$orig, $configclass->config || {} );
>
> };
>
> override 'hook_logger' => sub {
> my $self = shift;
>
> # Optional logger from class
> my $logger = $self->config->{Logger};
> if ( defined $logger ) {
> die "Config Logger requires a Class key"
> unless $logger->{Class};
>
> my $logclass = $load_class->( $logger->{Class} );
> $self->log( $logclass->new( @{ $logger->{Config} || [] } ) );
>
> $self->log->debug( qq/Initialized logger: "$logclass"/ );
>
> }
>
> };
>
> Now, realistically even the *second* and extended implementation is
> still notably generic and *for me* this is even enough to place as a
> *base class* to every application as this is how I will lay things
> out. Plack::Util seems to be a fair assumption to be loaded as the end
> result is a PSGI app, and Plack::Runner is going to pull this in. For
> the nosy, the Logger class in this case is a mere wrapper around
> Log::Log4perl in this case, and would only get the logger instance if
> it had already been initialized. You can (and I do) set up Plack
> middleware to do the same thing, making the same logger available to
> other PSGI parts that might be used in your application, all without
> needing to wrap context to get at the logger, or explicitly call
> Log::Log4pperl::get_logger as we might just want to change that to a
> different logger at some stage.
>
> So general thoughts are:
> 1. Have a config class that is external to Catalyst logic. You can use
> it elsewhere without hassle.
> 2. Have a hook to hang that config on and get it early; because
> 3. Hang a logger on a hook before 'setup' is called so you can get the
> startup logging on debug
> 4. Pull in the plugins from Config so there isn't a need to keep
> modifying that code in the context class for every app
>
> Also minimising the selection of Plugins. I do try to keep this to
> session and auth stuff for convenience, and again have these as just
> thin layers over Plack Middleware. Other things can be delegated to
> role applicator stuff, which I haven't typed in here.
>
> Anyone else have thoughts? Alternate favourite methods for layout?
>
>
>
>
> ---
> This email is free from viruses and malware because avast! Antivirus
> protection is active.
> http://www.avast.com
>
>
> _______________________________________________
> List: Catalyst at lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive:
> http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/
---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com
More information about the Catalyst
mailing list