Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
MooseX::App::Tutorial(User Contributed Perl DocumentatMooseX::App::Tutorial(3)

       MooseX::App::Tutorial - getting started with MooseX::App

       To create a simple command-line application with	MooseX::App you	need

       o   A base class

       o   Multiple command classes (unless you	use MooseX::App::Simple)

       o   and an invocation script

       The simplest possible base class	just contains a	single use statement
       which loads all roles and metaclasses you need to get started as	well
       as Moose.

	 package MyApp;
	 use MooseX::App;

       The base	class can be customized	by

       o   adding MooseX-App plugins

       o   changing the	command-class namespace

       o   defining global options/parameters used by all command classes
	   (only if command classes inherit from the base class)

       o   add documentation (either POD or via	the app_usage and
	   app_description functions)

       o   and changing	MooseX-App flags (eg. turn fuzzy matching off)

       o   Adding Moose	attribute documentation	and type constraints.

       It is also possible to add global options and parameters	to your	base
       class and inherit your command classes from the base class (inheriting
       your command classes from your base class is purely optional).

	 package MyApp;
	 use MooseX::App qw(Config Color); # Loads the Config and Color	plugin

	 # This	attribute will be available at the command line
	 option	'some_global_option' =>	(
	     is		       => 'rw',
	     isa	       => 'Str',
	     required	       => 1,
	     documentation     => q[Some important global option],

	 # This	attribute will not be exposed
	 has 'private_option' => (
	     is		     =>	'rw',
	     isa	     =>	'Str',


       When adding attributes make sure	to include a documentation and
       possibly	a type constraint. MooseX-App will use this information	to
       build a user documentation for each attribute and command. The
       attribute documentation can be customized by providing additional
       options (see MooseX::App::Meta::Role::Attribute::Option)

       After you created a base	class it is time to create one class for each
       command you want	to provide (unless you are using MooseX::App::Simple).
       The command classes must	reside in the namespace	of the base class (eg.
       'MyApp::SomeCommand').  You can also deeply nest	classes	in the main
       namespace to create subcommand.	The namespace for the command classes
       however can be changed via the 'app_namespace' function in the base
       class, or by simply registering command classes manually	via
       'app_command_register'. Use 'app_exclude' to exclude certain sub

       All command classes must	use MooseX::App::Command, which	will also load

	 package MyApp::SomeCommand;
	 use MooseX::App::Command;

       If you want to use global options defined in the	base class you can
       optionally extend the base class	with your command class.

	 package MyApp::SomeCommand;
	 use MooseX::App::Command;
	 extends qw(MyApp);

       To provide a description	for each command you need to set the
       "command_short_description", "command_long_description" and optionally
       "command_usage" information. The	command	descriptions may contain

	command_short_description q[This command is awesome];
	command_long_description q[This	command	is so awesome, yadda yadda yadda];

       If not provided,	MooseX-App will	try to parse the command description
       from the	POD. The NAME or ABSTRACT section will become the short
       description and the DESCRIPTION or OVERVIEW section the long

       The usage header	can either be set by adding "command_usage"

	command_usage q[script some_command --some_option NUMBER];

       or by adding a SYNOPSIS or USAGE	section	to the module' POD. If neither
       command_usage nor SYNOPSIS/USAGE	are set, then the usage	header will be

       Attributes can be documented using the Moose built-in "documentation"
       option as well as "cmd_tags", "cmd_flag"	and "cmd_aliases" which	are
       defined by MooseX-App (see MooseX::App::Meta::Role::Attribute::Option)

	 option	'some_option' => (
	     is		       => 'rw',
	     isa	       => 'Integer',
	     required	       => 1,
	     documentation     => q[Some important option],
	     cmd_tags	       => [qw(Important!)], # Extra tags. Displayed in square brackets
	     cmd_aliases       => [qw(s)], # Alternative option	name
	     cmd_flag	       => 'some', # Option should be called 'some' instead of 'some_option'

       It is also possible to define positional	parameters with	the
       'parameter' keyword

	 # This	attribute will become a	positional parameter
	 parameter 'id'	=> (
	     is		       => 'rw',
	     isa	       => 'Int',
	     documentation     => q[Some ID],
	     required	       => 1,

       The help	for this command would look something like this	(with
       autogenerated usage headers):

	   my_app some_command <ID> [long options...]
	   my_app help
	   my_app some_command --help

	   This	command	is awesome, yadda yadda	yadda

	   ID		      Some ID [Integer;	Required]

	   --config	      Path to command config file
	   --some -s	      Some important option [Required; Integer;	Important!]
	   --help --usage -?  Prints this usage	information. [Flag]

       In case you want	to include an attribute	not defined with the 'option'
       or 'parameter' keyword you can use the 'AppOption' trait	and 'cmd_type'
       attribute. (see MooseX::App::Meta::Attribute::Option).

	 has 'myoption'	=> (
	     is		       => 'rw',
	     traits	       => ['AppOption'], # only	required if not	definded in base or command class
	     cmd_type	       => 'option', # or 'parameter'

       Finally your command classes will need a	method which should be called
       if the command is invoked by the	user.

	sub run	{
	   my ($self) =	@_;
	   # do	something

       If you need to implement	only a single command you should use
       MooseX::App::Simple instead of MooseX::App, and omit command classes.
       In this case of course you have to declare all options and implement
       the application logic in	the base class:

	 package MyApp;
	 use MooseX::App::Simple qw(Config); # Loads the Config	plugin

	 option	'some_global_option' =>	(
	     is		       => 'rw',
	     isa	       => 'Str',
	     documentation     => q[Some important global option],

	 sub run {
	    my ($self) = @_;
	    # do something


       Once you	have the base and command classes ready, you need to write a
       small invocation	script:

	#!/usr/bin/env perl
	use MyApp;

       "MyApp->new_with_command" will try to instantiate a command class. If
       it fails	it will	return a MooseX::App::Message::Envelope	object
       possibly	containing an error message and	a usage	message. Since
       MooseX::App::Message::Envelope follows the Null object pattern you can
       call any	method on it without checking the object type. Note that
       MooseX::App::Message::Envelope objects may also have an exitcode	set.
       In this case whenever the object	gets stringified, it prints on
       STDERR/STDOUT and exits the program using the specified exitcode. Don't
       use the ovleroaded stingification if you	don't want this	behaviour.

       You can also pass default/fallback values to the	constructor

	#!/usr/bin/env perl
	use MyApp;
	MyApp->new_with_command( some_global_option => 'something' )->run();

       If using	MooseX::App::Simple your invocation script needs some
       modification and	call "new_with_options"	instead	of "new_with_command".

	#!/usr/bin/env perl
	use MyApp;

       Once you	have a basic working application you can make it more user
       friendly	by adding documentation	(either	by using the app_description,
       app_usage, command_short_description, ... functions or by writing POD),
       Moose type constraints and additional plugins (eg. colorise the

       Make sure to invoke your	script with APP_DEVELOPER=1 during
       development. This will perform additional checks	for detecting wrong
       attribute/type constraint combinations, name clashes, ...

       If you want custom behaviour you	could start writing your own

       Make sure to run	your application in the	APP_DEVELOPER=1	environment.
       In this mode additional sanity checks will be performed upon startup.

perl v5.32.1			  2019-05-13	      MooseX::App::Tutorial(3)


Want to link to this manual page? Use this URL:

home | help