[ Home | Main Table Of Contents | Table Of Contents | Keyword Index ]

cmdr-spec-dsl-parameter(n) 1.2 doc "Cmdr, a framework for command line parsing and dispatch"

Name

cmdr-spec-dsl-parameter - Cmdr - Parameter Specification Language

Table Of Contents

Synopsis

Description

Welcome to the Cmdr project, written by Andreas Kupries.

For availability please read Cmdr - How To Get The Sources.

This document is for users of the cmdr framework. It introduces the domain-specific language for the specification of parameters in detail.

Related Specification Documents

  1. Cmdr - Introduction to the Specification Language

  2. Cmdr - Officer Specification Language

  3. Cmdr - Private Specification Language

  4. Cmdr - Parameter Specification Language

  5. Cmdr - Runtime Processing Flow

Language Reference

The parameters of privates are the heart of the system, providing the space needed to transfer command arguments to their implementations, and having the most attributes controlling their behaviour.

This complexity is strongly mitigated by the use of sensible defaults for each of the three possible kinds of parameter, i.e. positional inputs, named options", and state hidden from the command line.

Each kind has its own construction command in the language for privates (See Cmdr - Private Specification Language) which specifies the common information which cannot have defaults, i.e.

  1. the name identifying it to the system,

  2. the help text describing it in informal speech, and, of course,

  3. the parameter specification itself, using the commands of this section.

Naming

We have two commands to influence the visible naming of all parameters.

As background, all parameters are named, to properly identify them within the framework and other Tcl code, i.e. in the various callbacks and the private's action. This system name has to be unique within the private a parameter belongs to. Beyond that however the visible (i.e. non-term state]) parameters have to be identified by users within help texts, and, in the case of options, for detection during the Parsing phase. That is the visible naming, seen by a user of any application whose command line processing is based on the Cmdr framework.

label text

This command declares the parameter's visible name, if different from the system name used as the default. Note that in most cases this default is good enough, obviating the need for this command.

The only use case seen so far is when two semantically equivalent input and option parameters clash, forcing the use of different system names due to the requirement for their uniqueness, yet also use the same visible name and flag within the help to highlight their connection and equivalence.

alias name

For options the label command and its default specifies the name of the primary flag recognized during the Parsing phase. If that is not enough for a specific option this command allows the specification of any number additional flags to be recognized.

Note however that the framework automatically recognizes not only the specified flag(s), but also all their unique prefixes, obviating the need for this command in many cases.

neg-alias name
!alias name

This command applies only to boolean options. For them it allows the specification of any number additional flags to be recognized, which are aliases of its inverted form, i.e. of --no-FOO for an option FOO.

This in contrast to aliases, which are for the regular form of the option.

Note further that the framework automatically recognizes not only the specified flag(s), but also all their unique prefixes, obviating the need for this command in many cases.

General control

The general handling of a parameter is influenced by three commands:

no-promotion

When the framework encounters an unknown flag during the Parsing phase it will not unconditionally throw an error about it, but first check if the next available input parameter (if any) could accept the flag string as its value, per that input's validation type, and if yes, does so.

This command causes the rejection of such flag strings by this parameter on general principle, without having to validate it.

Note that it is only useful for and applicable to input parameters.

optional

This command marks the parameter as optional, i.e. as something the user may skip on the command line, with the application supplying sensible defaults (See section Representations). This causes the framework to expend some effort in the Parsing phase to determine whether an argument word should be assigned to the parameter, or not.

This setting is only applicable to inputs, as options are optional by definition, and state is hidden.

test

This command is related to the above, switching the runtime from the standard regime for acceptance (based on counting and thresholds) to a different regime based on validation.

More details are explained in section Parsing of Cmdr - Runtime Processing Flow.

undocumented

This command excludes the parameter from the generated help.

Its main use case is the hiding of options giving an application developer access to the internals of their application, something a regular user has no need of, and doesn't have to know about.

Representations

An important concept of parameters is something taken up from Tcl itself. The differentation between string and internal representations. Where Tcl uses internal representations to speed up its execution here this separation is that of between the information delivered to the application by a user, and the application-specific data structures behind them.

All parameters will have an internal representation. This is usually derived from the string representation provided by the user. The details of that process are explained in section Validation. However we have cases where the user cannot specify a string representation (states), or is allowed to choose not to (optional inputs, options). For these cases three specification commands are made available enabling us to programmatically choose the internal representation.

default value

This command specifies a constant default value for the internal representation.

generate cmdprefix

This command specifies a callback to compute the default internal representation at runtime. This is useful if the default is something which cannot be captured as a fixed value. An example would be a handle to some resource, or a dynamically created object.

The command prefix is invoked with a single argument, the cmdr::parameter instance for which to generate the internal representation.

The commands default and generate exclude each other, i.e. only of them can be specified, but not both. If neither are specified, and we need a default (see the cases above) then a default is chosen by the framework itself, as per the two rules below:

  1. Use the empty string for a list parameter.

  2. Use the default value supplied by the chosen validation type (See section Validation).

interact ?prompt?

This command actually does not specify an internal representation, but activates another method for the user to specify the string representation of the parameter, outside of the command line. As such it has priority over either default and generate, and can be specified with either. A parameter marked with it will interactively ask the user for a value if none was specified on the command line.

The default for the prompt is derived from the parameter's system name.

To recapitulate:

  1. A string representation specified on the command line has the highest priority and goes through the chosen validation type to get the associated internal representation.

  2. If activated via interact a small shell is run asking the user for a value (or more, as per list, see below). The result goes through the chosen validation type to get the associated internal representation.

  3. After that the internal representation is either the declared default value, or the result of invoking the generate callback. As internal representations the resulting values are not run through the chosen validation type.

list

This command marks the parameter as a list. In other words, its string and internal representation is actually a list of such, instead of a single value. By default all parameters are scalar.

This affects the handling of the parameter by the Parsing phase, by interact above, and the use of the validation type. The last two ask for multiple values, and feed the elements of the string representation separately through validation instead of just the string value in one. In the Parsing phase treatment of options changes from keeping only the last assigned value to the accumulation of all values. Similarly a list-input takes all the remaining words on the command line for itself instead of just the current word. Because of this list-inputs are only allowed as the last parameter of a private.

The last two specification commands dealing with the representations control when the internal representation is created.

defered

This command marks a parameter as defered, causing its internal representation to be computed on first access to its value. This is the default for state parameters.

immediate

This command marks a parameter as immediate, causing its internal representation to be computed in the Completion phase. This is the default for input and option parameters.

Validation

The answer to the necessity of moving between the string and internal representations described in the previous section are the validation types. Given a string representation they either return the associated internal representation or raise an error, signaling that the string was illegal. This part of their work, the verification of the legality of the input string gave them their name.

The general concept of validation types was taken from snit, and modified to suit Cmdr. Where snit's types expect only a single method to validate the input Cmdr expects all types to support an ensemble of four methods. One for the basic validation and transformation of the input, another for the release of any internal representation so generated, plus two more for delivery of a default representation and support for command line completion.

validate cmdprefix

This command specifies a validation type for the parameter, in the form of a command prefix (or the name of one of the builtin types, see package cmdr::validate). The set of methods this callback has to support, their signatures, etc. are all explained in Cmdr - Writing custom validation types. This document contains the implementation of the standard boolean validation type as an example as well.

Because of the same necessity all parameters must have a validation type assigned to them, and the system will choose which, if the user did not. This choice is made as per the six rules below and always returns one of the standard types implemented by package cmdr::validate.

  1. Use identity if a generate callback is specified.

  2. Use boolean if no default is specified and the parameter is an option.

  3. Use identity if no default is specified and the parameter is an input.

  4. Use boolean if the specified default value is a Tcl boolean.

  5. Use integer if the specified default value is a Tcl integer.

  6. Use identity as fallback of last resort.

presence

This command is best discussed as part of the wider area of boolean options, i.e. options with the standard validation type boolean assigned to them. These have associated special behaviours, both in the handling of the specification, and in the Parsing phase.

First, normal boolean options. They have automatic aliases declared for them, derived from their primary flag. An option named "foo" will have an alias of "no-foo", and the reverse. In the Parsing phase the "foo" and "no-foo" flags have inverse semantics, and both are allowed to occur without option argument following the flag. This is in contrast to all other options which must have such an argument. The parser essentially uses the validation type to decide if the word after the flag is a proper boolean value, or not, i.e. an argument to assign to the parameter, or not.

Now presence declares a variant of the above, a boolean option without the automatic aliases, and never taking an argument during parsing. Its mere presence on the command line will set its parameter. Their default value is consequently fixed to false as well.

Signaling

Of the four callbacks supported by parameters the first two, generate and validate have been described already, in the sections Representations and Validation, respectively.

This section explains the commonalities between the callbacks in general, and the last two, for notifications about state changes in detail.

All callbacks are treated as command prefixes, not scripts. There are no placeholder substitutions, only arguments added to each command prefix on invokation. This does not harm the generality of the system, as complex scripts can be used via procedures or equivalents (i.e. apply).

The two callbacks not yet described are the state-change callbacks through which the framework can actively drive parts of the application while processing the command line, whereas normally the application drives access to parameters through their methods.

when-complete cmdprefix

This command declares a state-change callback to invoke when the internal representation of the parameter is generated from the string representation, or the various ways of getting a default.

The callback is invoked with two arguments, the cmdr::parameter instance of the changed parameter, and its internal representation, in this order.

Multiple callbacks can be declared, by using this command several times. The callbacks are executed in the order of their declaration.

when-set cmdprefix

This command declares a state-change callback to invoke when the string representation of the parameter is set during command line parsing.

The callback is invoked with two arguments, the cmdr::parameter instance of the changed parameter, and its string representation, in this order.

Multiple callbacks can be declared, by using this command several times. The callbacks are executed in the order of their declaration.

Due to their nature these callbacks are invoked at runtime during either the Parsing, Completion, or Execution phases. The details are shown in the table below. The specification commands influencing the timing, i.e. forcing the use in a specific phase are shown in the intersection of callback and phase.

                    | Dispatch | Parsing | Completion  | Execution
--------------------+----------+---------+-------------+-----------
validate (default)  | *        |         |             |          
--------------------+----------+---------+-------------+-----------
validate (complete) |          | *       | immediate   | defered
when-set            |          | *       |             |          
--------------------+----------+---------+-------------+-----------
generate            |          |         | immediate   | defered
validate (validate) |          | test    | immediate   | defered
validate (release)  |          | test    | immediate   | defered
--------------------+----------+---------+-------------+-----------
when-complete       |          |         | immediate   | defered
--------------------+----------+---------+-------------+-----------

Supporting commands

The parameter language currently provides four supporting commands which provide quick access to commonly useful functionality. All the helper command return anonymous procedures for use with the various callbacks of a parameter.

stop!

The returned callback unconditionally declares its parameter as undefined. This is useful in combination with generate to abort value processing for an optional input after the interaction stage.

This is for inputs which are not optional per se, but declared as such to allow interactive entry when missing. A

    generate [stop!]

clause then ensures an error when interactive entry gets disabled, either global, or for the specific command.

touch name value

The returned callback sets the named sibling parameter to the specified value. A simple method of communication between parameters of a command.

Useful for use with when-set and/or when-complete

touch? name value

The returned callback sets the named sibling parameter to the specified value, if and only if that parameter exists. A simple method of communication between parameters of a command, where the sibling may not exists, depending on usage context.

Useful for use with when-set and/or when-complete

disallow name

This command simplifies the use of the parameter's lock method to signal that the named parameter cannot be used with this one, returning a callback generating all the proper arguments required by the method, especially the name of the parameter invoking the lock.

Useful for use with when-set.

Please continue reading with Cmdr - Runtime Processing Flow.

Related Documents

  1. Cmdr - Introduction to the project

  2. Cmdr - License

  3. Cmdr - Log of Changes

  4. Cmdr - How To Get The Sources

  5. Cmdr - The Installer's Guide

  6. Cmdr - The Developer's Guide

Bugs, Ideas, Feedback

Both the package(s) and this documentation will undoubtedly contain bugs and other problems. Please report such at Cmdr Tickets.

Please also report any ideas you may have for enhancements of either package(s) and/or documentation.

Keywords

arguments, command hierarchy, command line completion, command line handling, command tree, editing command line, help for command line, hierarchy of commands, interactive command shell, optional arguments, options, parameters, processing command line, tree of commands