$ bin/pie-factory --help
$ bin/pie-factory -h
$ bin/pie-factory help
          
usage: pie-factory [options] [commands]
You have inherited a pie factory.  Use your powers wisely.
COMMANDS
pie-factory bake <pie>              Bake a pie
pie-factory eat  <pie>              Eat a pie
pie-factory recipe list             List pie recipes
pie-factory recipe show   <recipe>  Display a recipe
pie-factory recipe add    <recipe>  Add a recipe
pie-factory recipe delete <recipe>  Delete a recipe
pie-factory throw <pie> <target>    Throw a pie at something
pie-factory help <cmd>              Get help with a command
OPTIONS
  -v, --version  Show version
  -h, --help     Show this message
          
$ bin/pie-factory throw --help
$ bin/pie-factory throw -h
$ bin/pie-factory help throw
          
usage: pie-factory throw <pie> <target> [options]
Throw <pie> at <target>.  Valid values for <pie> are apple, 
rhubarb, or mud.
OPTIONS
    -a, --angrily  Curse the target after throwing the pie
    -s, --speed    Throw the pie this many mph
    -h, --help     Show this message
          
$ bin/pie-factory recipe --help
$ bin/pie-factory recipe -h
$ bin/pie-factory recipe
$ bin/pie-factory help recipe
          
Subcommands for: piefactory recipe
pie-factory recipe list             List pie recipes
pie-factory recipe add    <recipe>  Display a recipe
pie-factory recipe delete <recipe>  Add a recipe
pie-factory recipe show   <recipe>  Delete a recipe
          
~/code/pie-factory $ tree
.
├── bin
│   └── pie-factory
└── lib
    ├── PieFactory
    │   └── Cmd
    │       ├── Bake.pm
    │       ├── Eat.pm
    │       ├── Help.pm
    │       ├── Recipe
    │       │   ├── Add.pm
    │       │   ├── Delete.pm
    │       │   ├── List.pm
    │       │   └── Show.pm
    │       └── Throw.pm
    └── PieFactory.pm
5 directories, 10 files
          
$ pie-factory throw rhubarb-pie Batman
          
# inside bin/pie-factory:
use MooX::Commander;
my $commander = MooX::Commander->new(
    base_class   => 'PieFactory',
    class_prefix => 'Cmd',  # optional, default value is 'Cmd'
);
$commander->dispatch(argv => \@ARGV);
          
package PieFactory::Cmd::Throw;
use Moo;
sub go {
    my ($self, $pie, $target) = @_;
    # print usage and then exit unsuccessfully
    $self->usage() unless $pie && $target;
    # print "Not a valid value", 
    # print usage, and exit unsuccessfully
    $self->usage("Not a valid value for <pie>") 
        unless $pie eq 'rhubarb-pie';
    $self->throw($pie => $target);
}
# Print usage and exit unsuccessfully.
sub usage { 
    my ($self, $msg) = @_;
    print $shift, "\n" if $msg;
    print "usage: pie-factory throw <pie> <target> [options]...";
    exit 1; 
}
          
package PieFactory::Cmd::Throw;
use Moo;
with 'MooX::Commander::HasOptions';
sub go {
    my ($self, $pie, $target) = @_;
    # print usage and then exit unsuccessfully
    $self->usage() unless $pie && $target;
    # print "Not a valid value", 
    # print usage, and exit unsuccessfully
    $self->usage("Not a valid value for <pie>") 
        unless $pie eq 'rhubarb-pie';
    $self->throw($pie => $target);
}
# Print usage and exit unsuccessfully.
sub usage { "usage: pie-factory throw <pie> <target> [options]..."; }
          
package PieFactory::Cmd::Throw;
use Moo;
with 'MooX::Commander::HasOptions';
sub go {
    my ($self, $pie, $target) = @_;
    # print usage and then exit unsuccessfully
    $self->usage() unless $pie && $target;
    # print "Not a valid value", 
    # print usage, and exit unsuccessfully
    $self->usage("Not a valid value for <pie>")
        unless $pie eq 'rhubarb-pie';
    $self->curse_loudly() if $self->options->{angrily};
    $self->throw($pie => $target, $self->options->{speed});
}
# Print usage and exit unsuccessfully.
sub usage { "usage: pie-factory throw <pie> <target> [options]..." }
# This array is used to configure Getopt::Long
sub _build_options {(
    'angrily|a',
    'speed|s=i',
)}
          
package PieFactory::Cmd::Recipes;
use Moo;
with 'MooX::Commander::HasSubcommands';
          
package PieFactory::Cmd::Recipes;
use Moo;
with 'MooX::Commander::HasSubcommands';
usage { "Subcommands for: piefactory recipes..." }
          Create subcommand classes the same way you would build any command class.
package PieFactory::Cmd::Help;
use Moo;
with 'MooX::Commander::IsaHelpCommand';
          
package PieFactory::Cmd::Help;
use Moo;
with 'MooX::Commander::IsaHelpCommand';
sub usage { "usage: pie-factory [options] [commands]..." }
          MooX::Commander->new(...)->dispatch(...)with 'MooX::Commander::HasOptions'with 'MooX::Commander::HasSubcommands';with 'MooX::Commander::IsaHelpCommand';