NOTE: I'd like to consider this a sort of RFC as well, comments welcome!
Wow, so after a nice ass kicking by my mentor Matt Trout, I hunkered down and whipped out a pretty tangible set of code for Catalyst::Script and Catalyst::ScriptRunner.
Here's the rundown.
Instead of having our scripts do a bunch of work, I've moved all the script guts out of the scripts, and created a class for each of them, and Moosificated them. So we have Catalyst::Script::Test, Catalyst::Script::Create, Catalyst::Script::Server, Catalyst::Script::FastCGI and Catalyst::Script::Test. These each contain the functionality that the scripts originally had, wrapped in a nice little Moose container. Catalyst::ScriptRunner simply takes the requested class, and runs it with arguments thanks to MooseX::Getopt. I've finished with all but Catalyst::Script::Create, and I'll surely have to branch MooseX::Getopt and hack on it to get it to do what I want. Most of my tests pass, but the ones that don't will be fixed soon.
So, how does it look?
Like this:
Old myapp_fastcgi.pl:
#!/usr/bin/perl -w
BEGIN { $ENV{CATALYST_ENGINE} ||= 'FastCGI' }
use strict;
use warnings;
use Getopt::Long;
use Pod::Usage;
use FindBin;
use lib "$FindBin::Bin/../lib";
use MyApp;
my $help = 0;
my ( $listen, $nproc, $pidfile, $manager, $detach, $keep_stderr );
GetOptions(
'help|?' => \$help,
'listen|l=s' =>; \$listen,
'nproc|n=i' => \$nproc,
'pidfile|p=s' => \$pidfile,
'manager|M=s' => \$manager,
'daemon|d' => \$detach,
'keeperr|e' => \$keep_stderr,
);
pod2usage(1) if $help;
MyApp->run(
$listen,
{ nproc =>$nproc,
pidfile => $pidfile,
manager =>$manager,
detach => $detach,
keep_stderr => $keep_stderr,
}
);
1;
New myapp_fastcgi.pl:
#!/usr/bin/env perl
use FindBin qw/$Bin/;
use Catalyst::ScriptRunner;
Catalyst::ScriptRunner->run('Catalyst','FastCGI');
1;
Much better!The code to implement it is fairly simple as well, thanks to Moose:
package Catalyst::ScriptRunner;
use Moose;
sub run {
my ($self, $class, $scriptclass) = @_;
my $classtoload = "${class}::Script::$scriptclass";
Class::MOP::load_class($classtoload);
$classtoload->new_with_options->run;
}
1;
And Catalyst::Script::FastCGI:
package Catalyst::Script::FastCGI;
BEGIN { $ENV{CATALYST_ENGINE} ||= 'FastCGI' }
use FindBin qw/$Bin/;
use lib "$Bin/../lib";
use Pod::Usage;
use Moose;
use namespace::clean -except => [ qw(meta) ];
with 'MooseX::Getopt';
has help => ( isa => 'Bool', is => 'ro', required => 0, default => sub { 0 } );
has listen => ( isa => 'Int', is => 'ro', required => 1 );
has pidfile => ( isa => 'Str', is => 'ro', required => 0 );
has daemon => ( isa => 'Bool', is => 'ro', required => 0, default => sub { 0 } );
has manager => ( isa => 'Str', is => 'ro', required => 0 );
has keep_stderr => ( isa => 'Bool', is => 'ro', required => 0 );
has nproc => ( isa => 'Int', is => 'ro', required => 0 );
has detach => ( isa => 'Bool', is => 'ro', required => 0, default => sub { 0 } );
has app => ( isa => 'Str', is => 'ro', required => 1 );
sub run {
my $self = shift;
pod2usage() if $self->help;
my $app = $self->app;
Class::MOP::load_class($app);
$app->run(
$self->listen,
{
nproc => $self->nproc,
pidfile => $self->pidfile,
manager => $self->manager,
detach => $self->detach,
keep_stderr => $self->keep_stderr,
}
);
}
This is really cool, as it allows for SO much more flexibility, and a lot more clean code. Users can even drop in their own scripts if they pass it to Catalyst::ScriptRunner->run!







Leave a comment