+ All Categories
Home > Technology > Writing Modular Command-line Apps with App::Cmd

Writing Modular Command-line Apps with App::Cmd

Date post: 11-Jun-2015
Category:
Upload: ricardo-signes
View: 14,654 times
Download: 4 times
Share this document with a friend
Description:
It's easy to write command-line programs in Perl. There are a million option parsers to choose from, and Perl makes it easy to deal with input, output, and all that stuff. Once your program has gotten beyond just taking a few switches, though, it can be difficult to maintain a clear interface and well-tested code. App::Cmd is a lightweight framework for writing easy to manage CLI programs. This talk provides an introduction to writing programs with App::Cmd.
Popular Tags:
155
App::Cmd Writing Maintainable Commands
Transcript
Page 1: Writing Modular Command-line Apps with App::Cmd

App::CmdWriting Maintainable Commands

Page 2: Writing Modular Command-line Apps with App::Cmd

TMTOWTDI

Page 3: Writing Modular Command-line Apps with App::Cmd

There’s More Than One Way To Do It

Page 4: Writing Modular Command-line Apps with App::Cmd

Web

Page 5: Writing Modular Command-line Apps with App::Cmd

Web

•Mason

Page 6: Writing Modular Command-line Apps with App::Cmd

Web

•Mason

•Catalyst

Page 7: Writing Modular Command-line Apps with App::Cmd

Web

•Mason

•Catalyst

•CGI::Application

Page 8: Writing Modular Command-line Apps with App::Cmd

Web

•Mason

•Catalyst

•CGI::Application

•Maypole

Page 9: Writing Modular Command-line Apps with App::Cmd

Web

•Mason

•Catalyst

•CGI::Application

•Maypole

•Continuity

Page 10: Writing Modular Command-line Apps with App::Cmd

Web

•Mason

•Catalyst

•CGI::Application

•Maypole

•Continuity

•RayApp

Page 11: Writing Modular Command-line Apps with App::Cmd

Web

•Mason

•Catalyst

•CGI::Application

•Maypole

•Continuity

•RayApp

•Gantry

Page 12: Writing Modular Command-line Apps with App::Cmd

Web

•Mason

•Catalyst

•CGI::Application

•Maypole

•Continuity

•RayApp

•Gantry

•Tripletail

Page 13: Writing Modular Command-line Apps with App::Cmd

Web

•Mason

•Catalyst

•CGI::Application

•Maypole

•Continuity

•RayApp

•Gantry

•Tripletail

•CGI::ExApp

Page 14: Writing Modular Command-line Apps with App::Cmd

Web

•Mason

•Catalyst

•CGI::Application

•Maypole

•Continuity

•RayApp

•Gantry

•Tripletail

•CGI::ExApp

•OpenInteract

Page 15: Writing Modular Command-line Apps with App::Cmd

Daemons

Page 16: Writing Modular Command-line Apps with App::Cmd

Daemons

•POE

Page 17: Writing Modular Command-line Apps with App::Cmd

Daemons

•POE

•Danga

Page 18: Writing Modular Command-line Apps with App::Cmd

Daemons

•POE

•Danga

•Net::Server

Page 19: Writing Modular Command-line Apps with App::Cmd

Daemons

•POE

•Danga

•Net::Server

•Daemon::Generic

Page 20: Writing Modular Command-line Apps with App::Cmd

Daemons

•POE

•Danga

•Net::Server

•Daemon::Generic

•Proc::Daemon

Page 21: Writing Modular Command-line Apps with App::Cmd

Daemons

•POE

•Danga

•Net::Server

•Daemon::Generic

•Proc::Daemon

•Net::Daemon

Page 22: Writing Modular Command-line Apps with App::Cmd

Daemons

•POE

•Danga

•Net::Server

•Daemon::Generic

•Proc::Daemon

•Net::Daemon

•MooseX::Daemonize

Page 23: Writing Modular Command-line Apps with App::Cmd

Daemons

•POE

•Danga

•Net::Server

•Daemon::Generic

•Proc::Daemon

•Net::Daemon

•MooseX::Daemonize

•Event

Page 24: Writing Modular Command-line Apps with App::Cmd

TMTOWTDI

Page 25: Writing Modular Command-line Apps with App::Cmd

TMTOWTDI

•All the big problem sets have a few solutions!

Page 26: Writing Modular Command-line Apps with App::Cmd

TMTOWTDI

•All the big problem sets have a few solutions!

• So, when I needed to write a CLI app, I checked CPAN...

Page 27: Writing Modular Command-line Apps with App::Cmd

Command-Line Apps

Page 28: Writing Modular Command-line Apps with App::Cmd

Command-Line Apps

•App::CLI

Page 29: Writing Modular Command-line Apps with App::Cmd

Command-Line Apps

Page 30: Writing Modular Command-line Apps with App::Cmd

Command-Line Apps

:-(

Page 31: Writing Modular Command-line Apps with App::Cmd

Everybody writes command-line apps!

Page 32: Writing Modular Command-line Apps with App::Cmd

Why are there no good tools?

Page 33: Writing Modular Command-line Apps with App::Cmd

Second-Class Citizens

Page 34: Writing Modular Command-line Apps with App::Cmd

Second-Class Citizens

•That’s how we view them.

Page 35: Writing Modular Command-line Apps with App::Cmd

Second-Class Citizens

•That’s how we view them.

•They’re

Page 36: Writing Modular Command-line Apps with App::Cmd

Second-Class Citizens

•That’s how we view them.

•They’re

•hard to test

Page 37: Writing Modular Command-line Apps with App::Cmd

Second-Class Citizens

•That’s how we view them.

•They’re

•hard to test

•not reusable components

Page 38: Writing Modular Command-line Apps with App::Cmd

Second-Class Citizens

•That’s how we view them.

•They’re

•hard to test

•not reusable components

•hard to add more behavior later

Page 39: Writing Modular Command-line Apps with App::Cmd

Here’s an Example

Page 40: Writing Modular Command-line Apps with App::Cmd

Example Script

$ sink 30min “server mx-pa-1 crashed!”

Page 41: Writing Modular Command-line Apps with App::Cmd

Example Script

$ sink --list

who | time | event------+-------+----------------------------rjbs | 30min | server mx-pa-1 crashed!

Page 42: Writing Modular Command-line Apps with App::Cmd

Example Script

GetOptions(\%opt, ...);

if ($opt{list}) { die if @ARGV; @events = Events->get_all;} else { my ($duration, $desc) = @ARGV; Event->new($duration, $desc);}

Page 43: Writing Modular Command-line Apps with App::Cmd

Example Script

$ sink --list --user jcap

who | time | event------+-------+----------------------------jcap | 2hr | redeploy exigency subsystem

Page 44: Writing Modular Command-line Apps with App::Cmd

Example Script

GetOptions(\%opt, ...);

if ($opt{list}) { die if @ARGV; @events = $opt{user} ? Events->get(user => $opt{user}) : Events->get_all;} else { my ($duration, $desc) = @ARGV; Event->new($duration, $desc);}

Page 45: Writing Modular Command-line Apps with App::Cmd

Example Script

GetOptions(\%opt, ...);

if ($opt{list}) { die if @ARGV; @events = $opt{user} ? Events->get(user => $opt{user}) : Events->get_all;} else { my ($duration, $desc) = @ARGV; die if $opt{user}; Event->new($duration, $desc);}

Page 46: Writing Modular Command-line Apps with App::Cmd

Example Script

$ sink --start ‘putting out oil fire‘Event begun! use --finish to finish event

$ sink --list --open18. putting out oil fire

$ sink --finish 18Event finished! Total time taken: 23 min

Page 47: Writing Modular Command-line Apps with App::Cmd

Insult to Injury

Page 48: Writing Modular Command-line Apps with App::Cmd

Insult to Injury

•...well, that’s going to take a lot of testing.

Page 49: Writing Modular Command-line Apps with App::Cmd

Insult to Injury

•...well, that’s going to take a lot of testing.

•How can we test it?

Page 50: Writing Modular Command-line Apps with App::Cmd

Insult to Injury

•...well, that’s going to take a lot of testing.

•How can we test it?

•my $output = `sink @args`;

Page 51: Writing Modular Command-line Apps with App::Cmd

Insult to Injury

•...well, that’s going to take a lot of testing.

•How can we test it?

•my $output = `sink @args`;

• IPC::Run3 (or one of those)

Page 52: Writing Modular Command-line Apps with App::Cmd

Here’s a Solution

Page 53: Writing Modular Command-line Apps with App::Cmd

Command Breakdown

$ sink do --for 1hr --ago 1d ‘rebuild raid’

Page 54: Writing Modular Command-line Apps with App::Cmd

Command Breakdown

$ sink do --for 1hr --ago 1d ‘rebuild raid’

App

Page 55: Writing Modular Command-line Apps with App::Cmd

Command Breakdown

$ sink do --for 1hr --ago 1d ‘rebuild raid’

Command

Page 56: Writing Modular Command-line Apps with App::Cmd

Command Breakdown

$ sink do --for 1hr --ago 1d ‘rebuild raid’

Options

Page 57: Writing Modular Command-line Apps with App::Cmd

Command Breakdown

$ sink do --for 1hr --ago 1d ‘rebuild raid’

Args

Page 58: Writing Modular Command-line Apps with App::Cmd

Command Breakdown

$ sink do --for 1hr --ago 1d ‘rebuild raid’

Page 59: Writing Modular Command-line Apps with App::Cmd

“do” command

Page 60: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run {

Page 61: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

Page 62: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

Page 63: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago});

Page 64: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for});

Page 65: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Page 66: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Page 67: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Sink::Event->create(

Page 68: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Sink::Event->create( start => $start,

Page 69: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Sink::Event->create( start => $start, finish => $start + $length,

Page 70: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Sink::Event->create( start => $start, finish => $start + $length, desc => $desc;

Page 71: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Sink::Event->create( start => $start, finish => $start + $length, desc => $desc; );

Page 72: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Sink::Event->create( start => $start, finish => $start + $length, desc => $desc; );

Page 73: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Sink::Event->create( start => $start, finish => $start + $length, desc => $desc; );

print “event created!”;

Page 74: Writing Modular Command-line Apps with App::Cmd

“do” commandsub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Sink::Event->create( start => $start, finish => $start + $length, desc => $desc; );

print “event created!”;}

Page 75: Writing Modular Command-line Apps with App::Cmd

“do” command

Page 76: Writing Modular Command-line Apps with App::Cmd

“do” command

sub opt_desc {

Page 77: Writing Modular Command-line Apps with App::Cmd

“do” command

sub opt_desc { [ “start=s”, “when you started doing this” ],

Page 78: Writing Modular Command-line Apps with App::Cmd

“do” command

sub opt_desc { [ “start=s”, “when you started doing this” ], [ “for=s”, “how long you did this for”,

Page 79: Writing Modular Command-line Apps with App::Cmd

“do” command

sub opt_desc { [ “start=s”, “when you started doing this” ], [ “for=s”, “how long you did this for”, { required => 1} ],

Page 80: Writing Modular Command-line Apps with App::Cmd

“do” command

sub opt_desc { [ “start=s”, “when you started doing this” ], [ “for=s”, “how long you did this for”, { required => 1} ],}

Page 81: Writing Modular Command-line Apps with App::Cmd

“do” command

Page 82: Writing Modular Command-line Apps with App::Cmd

“do” command

sub validate_args {

Page 83: Writing Modular Command-line Apps with App::Cmd

“do” command

sub validate_args { my ($self, $opt, $args) = @_;

Page 84: Writing Modular Command-line Apps with App::Cmd

“do” command

sub validate_args { my ($self, $opt, $args) = @_;

Page 85: Writing Modular Command-line Apps with App::Cmd

“do” command

sub validate_args { my ($self, $opt, $args) = @_;

if (@$args != 1) {

Page 86: Writing Modular Command-line Apps with App::Cmd

“do” command

sub validate_args { my ($self, $opt, $args) = @_;

if (@$args != 1) { $self->usage_error(“provide one argument”);

Page 87: Writing Modular Command-line Apps with App::Cmd

“do” command

sub validate_args { my ($self, $opt, $args) = @_;

if (@$args != 1) { $self->usage_error(“provide one argument”); }

Page 88: Writing Modular Command-line Apps with App::Cmd

“do” command

sub validate_args { my ($self, $opt, $args) = @_;

if (@$args != 1) { $self->usage_error(“provide one argument”); } }

Page 89: Writing Modular Command-line Apps with App::Cmd

package Sink::Command::Do;use base ‘App::Cmd::Command’;

sub opt_desc { [ “start=s”, “when you started doing this” ], [ “for=s”, “how long you did this for”, { required => 1} ],}

sub validate_args { my ($self, $opt, $args) = @_;

if (@$args != 1) { $self->usage_error(“provide one argument”); } }

sub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Sink::Event->create( start => $start, finish => $start + $length, desc => $desc; );

print “event created!”;}

1;

Page 90: Writing Modular Command-line Apps with App::Cmd

package Sink::Command::Do;use base ‘App::Cmd::Command’;

sub opt_desc { [ “start=s”, “when you started doing this” ], [ “for=s”, “how long you did this for”, { required => 1} ],}

sub validate_args { my ($self, $opt, $args) = @_;

if (@$args != 1) { $self->usage_error(“provide one argument”); } }

sub run { my ($self, $opt, $args) = @_;

my $start = parse_ago($opt->{ago}); my $length = parse_duration($opt->{for}); my $desc = $args->[0];

Sink::Event->create( start => $start, finish => $start + $length, desc => $desc; );

print “event created!”;}

1;

Page 91: Writing Modular Command-line Apps with App::Cmd

Extra Scaffolding

Page 92: Writing Modular Command-line Apps with App::Cmd

Extra Scaffolding

package Sink;

Page 93: Writing Modular Command-line Apps with App::Cmd

Extra Scaffolding

package Sink;use base ‘App::Cmd’;

Page 94: Writing Modular Command-line Apps with App::Cmd

Extra Scaffolding

package Sink;use base ‘App::Cmd’;

1;

Page 95: Writing Modular Command-line Apps with App::Cmd

Extra Scaffolding

use Sink;Sink->run;

Page 96: Writing Modular Command-line Apps with App::Cmd

Testing Your App

Page 97: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

Page 98: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;

Page 99: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

Page 100: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

Page 101: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

my $error;

Page 102: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

my $error;my $stdout = do {

Page 103: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

my $error;my $stdout = do { local @ARGV = qw(do --for 8hr ‘sleeping’);

Page 104: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

my $error;my $stdout = do { local @ARGV = qw(do --for 8hr ‘sleeping’); stdout_from(sub {

Page 105: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

my $error;my $stdout = do { local @ARGV = qw(do --for 8hr ‘sleeping’); stdout_from(sub { eval { Sink->run; 1 } or $error = $@;

Page 106: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

my $error;my $stdout = do { local @ARGV = qw(do --for 8hr ‘sleeping’); stdout_from(sub { eval { Sink->run; 1 } or $error = $@; });

Page 107: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

my $error;my $stdout = do { local @ARGV = qw(do --for 8hr ‘sleeping’); stdout_from(sub { eval { Sink->run; 1 } or $error = $@; });}

Page 108: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

my $error;my $stdout = do { local @ARGV = qw(do --for 8hr ‘sleeping’); stdout_from(sub { eval { Sink->run; 1 } or $error = $@; });}

Page 109: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

my $error;my $stdout = do { local @ARGV = qw(do --for 8hr ‘sleeping’); stdout_from(sub { eval { Sink->run; 1 } or $error = $@; });}

like $stdout, qr/^event created!$/;

Page 110: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

my $error;my $stdout = do { local @ARGV = qw(do --for 8hr ‘sleeping’); stdout_from(sub { eval { Sink->run; 1 } or $error = $@; });}

like $stdout, qr/^event created!$/;is Sink::Event->get_count, 1;

Page 111: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::Output;

my $error;my $stdout = do { local @ARGV = qw(do --for 8hr ‘sleeping’); stdout_from(sub { eval { Sink->run; 1 } or $error = $@; });}

like $stdout, qr/^event created!$/;is Sink::Event->get_count, 1;ok ! $error;

Page 112: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => 3;use Test::App::Cmd;use Sink;

my ($stdout, $error) = test_app( Sink => qw(do --for 8hr ‘sleeping’));

like $stdout, qr/^event created!$/;is Sink::Event->get_count, 1;ok ! $error;

Page 113: Writing Modular Command-line Apps with App::Cmd

Testing App::Cmd

use Test::More tests => π;use Sink::Command::Do;

eval { Sink::Command::Do->validate_args( { for => ‘1hr’ }, [ 1, 2, 3 ], );};

like $@, qr/one arg/;

Page 114: Writing Modular Command-line Apps with App::Cmd

Growing Your App

Page 115: Writing Modular Command-line Apps with App::Cmd

Command Breakdown

$ sink do --for 1hr --ago 1d ‘rebuild raid’

Page 116: Writing Modular Command-line Apps with App::Cmd

Command Breakdown

$ sink do --for 1hr --ago 1d ‘rebuild raid’

Command

Page 117: Writing Modular Command-line Apps with App::Cmd

package Sink::Command::List;use base ‘App::Cmd::Command’;

sub opt_desc { ... }

sub validate_args { ... }

sub run { ... }

1;

Page 118: Writing Modular Command-line Apps with App::Cmd

package Sink::Command::List;use base ‘App::Cmd::Command’;

sub opt_desc { [ “open”, “only unfinished events” ], [ “user|u=s”, “only events for this user” ],}

sub validate_args { shift->usage_error(’no args allowed’) if @{ $_[1] }}

sub run { ... }

1;

Page 119: Writing Modular Command-line Apps with App::Cmd

package Sink::Command::Start;use base ‘App::Cmd::Command’;

sub opt_desc { ... }

sub validate_args { ... }

sub run { ... }

1;

Page 120: Writing Modular Command-line Apps with App::Cmd

package Sink::Command::Start;use base ‘App::Cmd::Command’;

sub opt_desc { return }

sub validate_args { shift->usage_error(’one args required’) if @{ $_[1] } != 1}

sub run { ... }

1;

Page 121: Writing Modular Command-line Apps with App::Cmd

More Commands!

$ sink do --for 1hr --ago 1d ‘rebuild raid’

$ sink list --open

$ sink start ‘porting PHP to ASP.NET’

Page 122: Writing Modular Command-line Apps with App::Cmd

More Commands!

$ sinksink help <command>

Available commands: commands: list the application’s commands help: display a command’s help screen

do: (unknown) list: (unknown) start: (unknown)

Page 123: Writing Modular Command-line Apps with App::Cmd

Command Listing

package Sink::Command::Start;

=head1 NAME

Sink::Command::Start - start a new task

=cut

Page 124: Writing Modular Command-line Apps with App::Cmd

Command Listing

package Sink::Command::Start;

sub abstract { ‘start a new task’; }

Page 125: Writing Modular Command-line Apps with App::Cmd

Command Listing

$ sink commands

Available commands: commands: list the application’s commands help: display a command’s help screen

do: record that you did something list: list existing events start: start a new task

Page 126: Writing Modular Command-line Apps with App::Cmd

Command Listing

Page 127: Writing Modular Command-line Apps with App::Cmd

Command Listing

$ sink help list

Page 128: Writing Modular Command-line Apps with App::Cmd

Command Listing

$ sink help list

Page 129: Writing Modular Command-line Apps with App::Cmd

Command Listing

$ sink help list

sink list [long options...]

Page 130: Writing Modular Command-line Apps with App::Cmd

Command Listing

$ sink help list

sink list [long options...] -u --user only events for this user

Page 131: Writing Modular Command-line Apps with App::Cmd

Command Listing

$ sink help list

sink list [long options...] -u --user only events for this user --open only unfinished events

Page 132: Writing Modular Command-line Apps with App::Cmd

Core Commands

Page 133: Writing Modular Command-line Apps with App::Cmd

Core Commands

•Where did “help” and “commands” come from?

Page 134: Writing Modular Command-line Apps with App::Cmd

Core Commands

•Where did “help” and “commands” come from?

•App::Cmd::Command::help

Page 135: Writing Modular Command-line Apps with App::Cmd

Core Commands

•Where did “help” and “commands” come from?

•App::Cmd::Command::help

•App::Cmd::Command::commands

Page 136: Writing Modular Command-line Apps with App::Cmd

Default Command

package Sink;use base ‘App::Cmd’;

1;

Page 137: Writing Modular Command-line Apps with App::Cmd

Default Command

package Sink;use base ‘App::Cmd’;

sub default_command { ‘help’ } # default

1;

Page 138: Writing Modular Command-line Apps with App::Cmd

Default Command

package Sink;use base ‘App::Cmd’;

sub default_command { ‘list’ }

1;

Page 139: Writing Modular Command-line Apps with App::Cmd

One-Command Applications

Page 140: Writing Modular Command-line Apps with App::Cmd

Simple Example

$ ckmail check -a work -a homeNo new mail.

Page 141: Writing Modular Command-line Apps with App::Cmd

Simple Example

$ ckmail -a work -a homeNo new mail.

Page 142: Writing Modular Command-line Apps with App::Cmd

The Lousy Way

Page 143: Writing Modular Command-line Apps with App::Cmd

The Lousy Way

•create Ckmail::Command::Check

Page 144: Writing Modular Command-line Apps with App::Cmd

The Lousy Way

•create Ckmail::Command::Check

•make empty Ckmail.pm

Page 145: Writing Modular Command-line Apps with App::Cmd

The Lousy Way

•create Ckmail::Command::Check

•make empty Ckmail.pm

•make “check” the default command

Page 146: Writing Modular Command-line Apps with App::Cmd

The Simple Way

package Ckmail::Command::Check;use base ‘App::Cmd::Command’;

sub opt_desc { ... }

sub run { ... }

1;

Page 147: Writing Modular Command-line Apps with App::Cmd

The Simple Way

package Ckmail::Command::Check;use base ‘App::Cmd::Simple’;

sub opt_desc { ... }

sub run { ... }

1;

Page 148: Writing Modular Command-line Apps with App::Cmd

The Simple Way

use Ckmail;Ckmail->run;

Page 149: Writing Modular Command-line Apps with App::Cmd

The Simple Way

use Ckmail::Command::Check;Ckmail::Command::Check->run;

Page 150: Writing Modular Command-line Apps with App::Cmd

App::Cmd::Simple

Page 151: Writing Modular Command-line Apps with App::Cmd

App::Cmd::Simple

•You write a command...

Page 152: Writing Modular Command-line Apps with App::Cmd

App::Cmd::Simple

•You write a command...

• ...but you use it like an App::Cmd.

Page 153: Writing Modular Command-line Apps with App::Cmd

App::Cmd::Simple

•You write a command...

• ...but you use it like an App::Cmd.

•Later, you can just demote it.

Page 154: Writing Modular Command-line Apps with App::Cmd

Any Questions?

Page 155: Writing Modular Command-line Apps with App::Cmd

Thank You!


Recommended