NAME
Decl::Semantics::Commandline - implements a command line parser in an event context, using Getopt::Lucid
VERSION
Version 0.01
SYNOPSIS
When running any script, the command line provides a first-line configuration and specification mechanism for the action to be taken. Perl simply provides the usual @ARGV list that C also does (granted, Perl does some of the irritating tasks for you that C doesn't), but it's up to you to do something sensible with that list.
This module allows you to define a command-line
tag that extracts various sorts of parameters from the command line, then takes the remaining parts of the list and treats it as a command to be executed.
It also provides a command loop (an internal command line) that can be embedded into any program to provide interactive services. A default set of commands could be provided as a debugger, for instance. (TODO: write a default set of commands as a debugger.)
Here's an example:
command-line argv (loop)
switch version "version|-V"
counter verbose "verbose|-v"
param config (anycase) "config|c"
list libraries "lib"
keypair def "define"
command start "start something" {
# Start something
}
command help "get help" {
# Print a help text
}
do {
# Handle unknown commands
}
The top five lines in our specification represent the five types of named command line argument supported. Anything left on the command line after all the named parameters have been consumed is treated as a command and passed to the appropriate "on" event. The search order is the usual one: if a like-named event isn't found in the command line, the parent node will be searched, and so on up to the root. If no matching "on" is found, the arglist is passed to the "do" handler, if there is one.
If a command is on the command line, it executes only after all parsing is finished; that is, the command is executed as the "start" action of the program.
If there is no command and "loop" is specified, the start action passes control to a Term::Shell REPL loop using the same event logic. If "loop=always" is specified, the loop will run even if an initial command is given. The shell will use the quoted labels of the events as summary text for the help system; for longer texts, a "help" tag must be given, like this:
command-line (loop)
command start "start something"
help
The "start" command is used to start something
and its help text may be multi-line. It is not
parsed.
do { # start something }
If no command was found on the command line, and no loop is specified, then the command line will not be marked as callable, so the program won't call it as its start action and will have to look elsewhere. If you never want the command line to be the start action, you can flag it:
command-line (nocall)
Normally, if not used as a command loop, the command line is just treated as a data source by name to permit its values to be queried from code elsewhere in the program. You can also specify a target data source like this:
command-line (store=system.argv)
switch verbose (anycase) "verbose|V"
There are four modifiers that can be added to named arguments:
command-line
switch parm1 (anycase) "parm1"
keypair parm2 (required) "parm2"
switch parm3 (needs=parm4) "parm3"
param parm4 (valid="\d+") "parm4"
The anycase
modifier makes the parameter case-insensitive. The required
modifier means that this value must be specified or an error is raised. The needs
modifier means that if parm3 is specified, then parm4 must also be specified or an error is raised. Finally, the valid
modifier is a regexp that must be matched or (wait for it ...) an error is raised.
One or more named error handlers may be provided:
command-line
keypair parm2 (required, needs=parm3) "parm2"
on error required {
print STDERR "You need to specify parm2.\n"
}
on error needs {
print STDERR "You can't specify parm2 without defining parm3.\n";
}
param parm3 (valid="\d+") "parm3"
on error valid {
print STDERR "parm3 must be numeric\n";
}
You can also provide a more heavy-duty validator:
command-line
param configfile "config"
valid { -r }
on error valid {
print STDERR "The configuration file you specified does not exist.\n";
}
Almost all of that is just the semantics of Getopt::Lucid, which really is the end-all and be-all of command line parsing.
defines(), tags_defined()
Called by Decl::Semantics during import, to find out what xmlapi tags this plugin claims to implement.
post_build
All the work is done in the post_build stage.
go
Called when the element is run (that is, when the shell is invoked, if any).
THE TERMINAL
The standard shell
STANDARD COMMANDS
The default command line provides debugging and introspection tools - a REPL - along with whatever commands you define. Those commands are defined in this section. They can be disabled for a given command line with (debug=no).
run_show, smry_show, help_show
The show
command shows the text of the current node (pages if necessary). If you give it one argument (e.g. "show code") it will use the argument to access the node's hashref and display the results. If the results are undefined, it will say so. If they're a scalar, it will print the scalar (through paging). If they're a ref, it will print the output of Data::Dumper (again through paging).
run_list, smry_list, help_list
The list
command lists the text of the current node (pages if necessary). With a single argument, lists the nodes with that tag.
run_goto, smry_goto, help_goto
The goto
command changes the current node by applying a "find" to the current node and switching the current node if it succeeds. If you provide neither [] nor (), the command assumes [].
prompt_str()
Returns the current prompt. TODO: make this overridable from the node definition.
AUTHOR
Michael Roberts, <michael at vivtek.com>
BUGS
Please report any bugs or feature requests to bug-decl at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Decl. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
LICENSE AND COPYRIGHT
Copyright 2010 Michael Roberts.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.