The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Getopt::Mixed::Help - combine Getopt::Mixed with usage and help

SYNOPSIS

    use constant DEFAULT_LOOPS => 10;
    use Getopt::Mixed::Help
        ('<filenames>...' => 'filenames to be processed',
         'ENV' => 'SCRIPT_OPT_',
         'ENV_' => 'SCRIPT_OPT_',
         'd>debug:i number' => 'turn on debugging information (*)',
         'e>execute' => 'do it without asking for confirmation',
         'f>force' => 'override all safety checks',
         'i>interactive' => 'asks for confirmation before doing it',
         'l>loops count' => 'number of loops to do',
         'n>no-execute' => 'just print what would be done without doing it',
         'q>quiet' => 'suppress all information',
         's>summary' => 'print summary information on exit',
         'v>verbose:i number' => 'turn on verbose information (*)',
         '(*)' => '(*) You may add a positive integer for a higher level.'
        );
    if ($opt_...

    export SCRIPT_OPT_INTERACTIVE=1
    test_script -d -v 2 --summary some_file.ext other_file.ext

ABSTRACT

Getopt::Mixed::Help is a simplified interface to Getopt::Long adding usage (help) functionality. It automatically adds the options -?, -h and --help (the last two configurable) to print the usage text. It allows to get option values from the environment (if the operating system it runs on supports environment variables). It can automatically get default values from Perl constants. It can also add different flavours of support for multiple options. Finally it supports debugging output of the options used.

So like Getopt::Long it is (just another) module that parses options passed on the command line into variables while removing them from @ARGV. Only normal parameters remain in @ARGV.

DESCRIPTION

The module uses a direct import mechanism called with a hash as parameter. The structure of the hash is as follows:

The key is a combined (SHORT > LONG [ARGUMENT SPECIFIER [VALUE IDENTIFIER]]) option description for the outdated module Getopt::Mixed, except for the VALUE IDENTIFIER which is simply included into the help text. The value following the key is simply the help text for this option. The examples should make everything clear even if you are not familiar with Getopt::Mixed.

If the second character of the first key is not >, the first key is taken as descriptive identifiers for additional parameters and the help for them.

Any key starting with ( and ending with ) will be interpreted as a footnote (additional help text) to the real options. They should be used at the end of the list only.

A key equal to ENV is used to get default values for the remaining options from the environment. For any option not initialised on the command line an environment variable with the prefix of the value following ENV and a rest of the name identical to the uppercase long option name (e.g. SCRIPT_OPT_DEBUG) will be checked. If this environment variable exists, it will be used to set the option. Note that in the name of the rest of the environment variable uppercase is used and hyphens are relaced with underlines.

A key equal to ENV_ is used in the same way as the key ENV. In addition it allows for a special environment variable with the prefix of the value following ENV followed by a single underline (_) as combined initialiser (for more than one option, e.g. export SCRIPT_OPT__='debug verbose=2'). Note that no whitespaces are allowed in the values of the options initialised this way as the string in the environment variable is parsed in a simple way.

The module defines the variable $optUsage containing the complete help text.

If an option debug exists and is choosen on the command line, this module will print all option values and all remaining parameters to standard error. The name of this option may be changed, see "changing the debug option" below in the "CHANGING DEFAULT BEHAVIOUR" section.

Perl constants with the prefix DEBUG_ and a name matching the option are used as default values for the options, see below for details.

EXPORT

The module automatically exports all option variables ($opt_) as well as the usage text ($optUsage).

OPTION DETAILS

parameter help ('parameter text' => 'parameter description')

If a script takes normal parameters (as oposed to options starting with a hyphen), their description for the help text must be the first parameter of the hash passed on import. It is also necessary that the second character of the key is not >. An example, if a script using this module accepts one or more filenames as parameters, you might want to use the following import parameter:

    '<filenames>...' => 'filenames to be processed'

This would produce the following help text:

    usage: script.pl [<options>] [--] <filenames>...

    filenames to be processed

combined options ('o>long-option ...' => 'option description')

Combined options are options that allow to use both a long and a short option to set the same option variable for a script (see Getopt::Mixed for details). In principle Getopt::Mixed::Help uses a syntax similar to Getopt::Mixed for the key of the import parameter, but it changes their sequence within the alias. The minimal key for the import parameter just uses the character of the short option followed by > followed by the long option (without --). It would define a boolean option variable, for example the import parameter

    'o>long-option' => 'some long option'

defines a boolean option with the identifier $opt_long_option that can be set with the short option -o and the long option --long-option (which may be abbreviated as described in Getopt::Mixed). Its help text would look as follows:

        -o|--long-option
            some long option

For string, integer or real number options the key of the import parameter must be extended with an argument specifier. There are 6 possible argument specifiers:

    =s for a mandatory string argument
    =i for a mandatory integer argument
    =f for a mandatory real number argument
    :s for an optional string argument
    :i for an optional integer argument
    :f for an optional real number argument

The argument specifieres may be followed by a blank and the value identifier, a short text describing the argument. This text will become part of the help text. If no describing text is specified, string will be used for strings, integer for integers and float for real numbers. Consider the import parameters of the following example:

    'd>directory=s directory' => 'name of the directory',
    'o>offset:f' => 'offset in the file in % (default 0.0)'

This defines a string option with a mandatory value and the indentifier $opt_directory as well as a real number option with an optional value and the identifier $opt_offset. The help text for these options would be:

        -d|--directory <directory>
            name of the directory
        -o|--offset [<float>]
            offset in the file in % (default 0.0)

For an optional value the default value that is used if no value is specified depends on its type. For strings it is an empty string (''), for integers it is 1 and for real numbers it is 0.0.

long options ('long-option ...' => 'option description')

If you run out of characters for short options you end up with the need for options that only exist as a long option. They are just declared like the combined options without the leading short option character and the >, e.g.

    'long-optional-string:s' => 'optional string'

The only pitfall with long options comes when the first option you declare is not a combined option and you don't have normal parameters as Getopt::Mixed::Help then would treat your long option declaration as a "parameter help". To avoid this just put a ->- declaration before it (see separator in "CHANGING DEFAULT BEHAVIOUR" below).

getting options from environment variables ('ENV' => 'SCRIPT_OPT_')

There are two special import parameter keys that allow your script to be able to read options from environment variables (if your operating system supports it).

The first key is the string 'ENV'. If it is defined, each option variable cat get its default value from an environment variable if that environment variable is set. The name of that environment variable is composed of the value of the 'ENV' import parameter and the name of the long option where all characters are turned into uppercase and all hyphens are replaces with underscores, e.g. for the import parameters

    'ENV' => 'MYSEARCH',
    'd>start-dir=s directory' => 'name of the first directory'

the option variable $opt_start_dir will be filled with the value of the environment variable MYSEARCHSTART_DIR if that is set and the option is not set on the command line.

The second environment import parameter key is the string 'ENV_'. It works similar to the other one except that it defines an environment variable that can be used to set a whole default command line at once (well, only its options and not if their values would contain blanks). For this key the name of that environment variable is composed of the value of the 'ENV_' import parameter followed by an underscore (_). To put several long options into the environment variable so created, just concatenate them together with blanks and without their leading --. If for example above's directory and offset options are preceeded by

    'ENV_' => 'MYSEARCH'

you could set the environment variable MYSEARCH_ from a shell like this:

    export MYSEARCH_='offset=12.5 directory=/tmp/somewhere'

But remember, this works for simple things only, for more complicated defaults from the environment you must create one variable for each option as described above. If you do both the value of the specific environment variable overwrites that of the combined one.

And a warnings for this features, if you use both environment import parameters (which is quite reasonable) you must use the same value for both of them, otherwise only the last one specified works.

footnotes

Sometimes you'll like to describe an option in more details, want to give additional information concerning more than one option or just like to add some more text at the end of a generated help. To do that, Getopt::Mixed::Help allows you to add just about any text you like to your import parameter list using keys that begin and end in parentheses. The key is not used any further, so you can use any text as long as you put it into parentheses. The text of the description is put into the help text as it is, but preceeded and followed by a newline.

Normally all footnotes are put at the end of the option list but theoretically you could also put one in-between to split the option list into two (or more) parts - the footnote is put into the help text just where it occurs.

DEFINING DEFAULT VALUES USING PERL CONSTANTS

If you define a Perl constant (use constant) beginning with DEFAULT_ and ending with the name of the long option where all characters are turned into uppercase and all hyphens are replaces with underscores, e.g. for the import parameters

    'd>start-dir=s directory' => 'name of the first directory'

a

    use constant DEFAULT_START_DIR => '.';

the variable $opt_start_dir will be initialised, if no other value is specified by environment variable or on the command line. (Options on the command line overrule the values specified in environment variables, which themselves overrule the default values of the Perl constants.)

In addition the default value will also be added to the help text for that option. The additional text will be put into parentheses and starts with the words defaults to. See below how to change that.

Note that all Perl constants with default values must be defined before the use command including this module, otherwise they have no effect. Also note that they must belong to the main:: namespace. And finally note that only simple values and array references are supported yet.

CHANGING DEFAULT BEHAVIOUR

Some declarations looking like silly declarations (they all start with a hyphen as the short option character) can change the behaviour of the module.

separator ('->-' => '')

The separator is only needed if you don't have normal parameters and your first option only comes in a long form, e.g. like in

    '->-' => '', 'long-optional-string:s' => 'optional string'

which produces the following help text:

    usage: script.pl [<options>] [--]

    options:  --long-optional-string [<string>]
                  optional string

Instead of the separator any of the other behavior changing declarations will have the same effect.

changing the help option ('->help' => 'H>Hilfe')

With ->help you can replace the default names h (as short option) and help (as long option) of the help options. The value part of this declaration must contain the new short option character followed by > followed by the long option (without --) as in a normal boolean option declaration.

Note that -? will always remain as help option as well and can not be renamed or removed!

changing the debug option ('->debug' => 'verbose')

With ->debug you can replace the default (long option) name debug of the debug option. (Remember that the module prints all options on STDERR if a long option called debug is declared and set.) The value part of this declaration is just the new long option name (without --).

Note that the debugging option still has to be declared as normal option as well.

changing the usage text ('->usage' => 'use as')

With this modifying option you can replace the text usage at the beginning of the help text with the string specified in the value part of this declaration.

Note that the variable used for the help text is still called $optUsage.

changing the options text ('->options' => 'switches')

With this modifying option you can replace the text options in the help text with the string specified in the value part of this declaration. Note that the string occurs two times.

Due to the way the help text is constructed this option has to be specified before the first normal option of the import (use) statement!

changing the default value text ('->default' => ' (init. %s)')

With this modifying option you can replace the text appended for options with default values set by Perl constant ( (defaults to %s)) in the help text with the string specified in the value part of this declaration. Note that the string must contain a %s as it is put together with sprintf (see "sprintf" in perldoc). You may also set this modifying option to undef to disable the additional help text.

Due to the way the help text is constructed this option has to be specified before the first normal option of the import (use) statement!

enabling multiple support ('->multiple' => ...)

This neat modifying option gives you support to process multiple occurances of the same option. It comes in two flavours, depending on the value part of the declaration:

multiple support using concatenation ('->multiple' => 'text')

With this flavour multiple occurances of the same option are (sort of) concatenated. The kind of concatenation depends on the type of the option: string options are concatenated (joined) with the given text put between each occurance, integers and floats are added together and boolean are just counted.

If you take the following example declaration of import parameters

    '->multiple' => ', ',
    'd>directory=s directory' => 'name of the directory',
    'o>offset:f' => 'offset in the file in % (default 0.0)'

and call the script using them with a command line like:

    -d a --offset -o=0.25 -d b -d=c -o=0.33

Now your option variable $opt_directory will be set to a, b, c and your option variable $opt_offset will be set to the value 0.58 (0.0 + 0.25 + 0.33).

Note that an empty string is a valid input for this flavour of multiple occurances, the strings then are just concatenated without anything between them.

multiple support using arrays ('->multiple' => undef)

With this flavour (yes, this one uses an explicit undef value to distinguish it from the last one) each option passed more than once will not be returned in a normal scalar variable but in a reference to an array.

For example take the declaration from the concatenation flavour and just replace the value part ', ' with undef. If you use this with the following options on your command line:

    -d a -o 0.25 --directory=b

This time your option variable $opt_offset will be a scalar with the value 0.25 but the option variable $opt_directory will be a reference to an array containing the values a and b (in that sequence).

It is up to you to handle the different variable types adequately! (But it is guaranteed that a ref will either return '' or 'ARRAY'.)

multiple per option support using arrays

A third method to support multiple options, again as arrays but only for selected options works by slightly modifying their import parameter key using a double >>. So suppose you have the following import parameters (without any ->multiple option at all):

    'd>>directory=s directory' => 'name of the directory',
    'o>offset:f' => 'offset in the file in % (default 0.0)'

If you now call your script with

    -d a -o0.25 --directory=b -o0.5

you'll end up with the value 0.5 in $opt_offset and a reference to an array with a and b in $opt_directory. So this gives you an easy way to enable multiple option support just for selected options easing the overhead for analysing all of them to be possible array references.

For long options (without a character for a short option) you just start them with the double >>.

Multiple options as string on a per-option-base is not supported, but you can get that with short statement like the following:

    $opt_directory = join(' ', @$opt_directory)
        if ref($opt_directory) eq 'ARRAY';

FUNCTIONS

import - main and only function

see above in the main documentation how to use it

One confession about the internals, this function doesn't use a real hash; it just uses the same syntax as it really expects an array of pairs (as most of you might have guessed already ;-).

KNOWN BUGS

The ones from Getopt::Long and maybe some more. Tell me, if you find one.

Getopt::Mixed::Help used to support setting short options using =, e.g. test_script -d -v=2. This no longer works as it this was a feature of the underlying Getopt::Mixed which does not exist in Getopt::Long.

SEE ALSO

Getopt::Long, Getopt::Mixed

The tests for this module were checked with Devel::Cover to make sure it is throughly tested. I highly recommend this module to others, it helped to find quirks that otherwise would have gone unnoticed!

AUTHOR

Thomas Dorner, <dorner (AT) cpan.org>

COPYRIGHT AND LICENSE

Copyright (C) 2004-2012 by Thomas Dorner

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.6.1 or, at your option, any later version of Perl 5 you may have available.