SimpleProc v1.0
The Simple Development Library procedures with extended argument syntax
Project: the Simple Development Library.
::Simple::Argument::check-type
args::Simple::Argument::information choices
procedure argument::Simple::Argument::information default
procedure argument::Simple::Argument::information defaultgiven
procedure argument::Simple::Argument::information description
procedure argument::Simple::Argument::information flaggiven
flag::Simple::Argument::information givenflags
::Simple::Argument::information isdefault
argument::Simple::Argument::information type
procedure argument::Simple::Proc::cget
?-checktype? ?-afterflags?::Simple::Proc::configure
?-checktype extbool? ?-afterflags integer?proc-ext
?-parseflags extbool? ?-checktype extbool? procedure arguments body::Simple::Proc::delete
procedure::Simple::Proc::information access
procedure::Simple::Proc::information alias
procedure::Simple::Proc::information args
procedure::Simple::Proc::information arguments
procedure::Simple::Proc::information body
procedure::Simple::Proc::information caller
?levels?::Simple::Proc::information checktype
procedure::Simple::Proc::information exists
procedure::Simple::Proc::information isextended
procedure::Simple::Proc::information issubcommand
procedure::Simple::Proc::information metadata
procedure::Simple::Proc::information parseflags
procedure::Simple::Proc::information runtimeparsing
procedure::Simple::Proc::information subcommands
command::Simple::Proc::information usage
procedure::Simple::Proc::move
sourceProcedure targetProcedure::Simple::Proc::resolve-alias
procedure::Simple::Script::Header::add
scriptName tag priority header::Simple::Script::Header::delete
scriptName ?pattern?::Simple::Script::Header::get
script ?pattern?::Simple::Script::Trailer::add
scriptName tag priority trailer::Simple::Script::Trailer::delete
scriptName ?pattern?::Simple::Script::Trailer::get
script ?pattern?::Simple::Script::append
scriptName scriptToAppend::Simple::Proc::NON-EXISTING-NAMESPACE
::Simple::Proc::TYPE-CHECKING-AND-NO-PARSE-FLAGS
::Simple::Proc::ARGS-MUST-BE-LAST
::Simple::Proc::NON-OPT-AFTER-OPT
::Simple::Proc::DEFAULT-NOT-ALLOWED
::Simple::Proc::ARGS-NOT-ALLOWED
::Simple::Proc::ARGS-LIST-OR-ANY
::Simple::Proc::NO-FLAG-PARSING-AND-NO-FLAGS
::Simple::Proc::NO-PARAM-FOR-FLAG
::Simple::Proc::CANT-BETWEEN-SUBCO-AND-NO-SUBCO
::Simple::Proc::NON-EXISTING-PROCEDURE
::Simple::Proc::NON-EXISTING-ARGUMENT
::Simple::Proc::NO-TYPE-CHOICE
::Simple::Proc::CANT-BE-CALLED-FROM-TOPLEVEL
::Simple::Script::DUPLICATED-TAG
::Simple::Proc::VALUE-REQUIRED
::Simple::Proc::ARRAY-NOT-ALLOWED
::Simple::Proc::OPTIONAL-FLAG
::Simple::Argument::check-type
args::Simple::Argument::information choices
procedure argument::Simple::Argument::information default
procedure argument::Simple::Argument::information defaultgiven
procedure argument::Simple::Argument::information description
procedure argument::Simple::Argument::information flaggiven
flag::Simple::Argument::information givenflags
::Simple::Argument::information isdefault
argument::Simple::Argument::information type
procedure argument::Simple::Proc::cget
?-checktype? ?-afterflags?::Simple::Proc::configure
?-checktype extbool? ?-afterflags integer?proc-ext
?-parseflags extbool? ?-checktype extbool? procedure arguments body::Simple::Proc::delete
procedure::Simple::Proc::information access
procedure::Simple::Proc::information alias
procedure::Simple::Proc::information args
procedure::Simple::Proc::information arguments
procedure::Simple::Proc::information body
procedure::Simple::Proc::information caller
?levels?::Simple::Proc::information checktype
procedure::Simple::Proc::information exists
procedure::Simple::Proc::information isextended
procedure::Simple::Proc::information issubcommand
procedure::Simple::Proc::information metadata
procedure::Simple::Proc::information parseflags
procedure::Simple::Proc::information runtimeparsing
procedure::Simple::Proc::information subcommands
command::Simple::Proc::information usage
procedure::Simple::Proc::move
sourceProcedure targetProcedure::Simple::Proc::resolve-alias
procedure::Simple::Script::Header::add
scriptName tag priority header::Simple::Script::Header::delete
scriptName ?pattern?::Simple::Script::Header::get
script ?pattern?::Simple::Script::Trailer::add
scriptName tag priority trailer::Simple::Script::Trailer::delete
scriptName ?pattern?::Simple::Script::Trailer::get
script ?pattern?::Simple::Script::append
scriptName scriptToAppendSynopsis: the Simple Development Library procedures with extended argument syntax.
Keywords: procedure, extended, argument, type and flag.
This package provides a way to create procedures with extended argument syntax. This syntax includes argument types (with optional run-time type checking) and flag arguments with or without parameters which may be automatically parsed or left for the user to parse.
Procedures are provided to create, delete, rename and get information about procedures with extended argument syntax, as well as others to handle arguments in the body of those procedures, such as assess whether certain flag has been given in the command line or assess whether the value of a flag is that flag value.
This package also allows to handle headers and trailers for code scripts. Each header or trailer is identified by a tag and, within a script, headers and trailers are ordered by increasing priority. Procedures are provided to add, get and delete script headers and trailers.
Extended syntax procedures are created via the ::Simple::Proc::create
procedure. The declaration specifies whether to perform run-time checking of the arguments types as well as whether to delegate the flag parsing to the user.
Extended argument syntax procedures can be deleted via ::Simple::Proc::delete
or renamed via ::Simple::Proc::move
. The ::Simple::Proc::information
procedure provides several subcommands to query information about extended argument syntax procedures: issubcommand
, subcommands
, runtimeparsing
, checktype
, parseflags
, exists
, body
, args
, usage
, arguments
, type
, default
, choices
, metadata
and description
.
The syntax of the extended arguments is similar to that of the arguments used by the opt
package distributed with Tcl, so the upgrade for users using that should be easy; in fact this package was implemented as an evolution of the opt
package for two reasons: 1) opt
is slow and 2) it was deprecated from Tcl 8.1 (made private, actually).
This argument syntax is of the form {name type ?value? description}
. There, "name" is the argument name, "type" its type, "value" its default value or choice list and "description" a string describing the argument. Types used by opt
are of the form "-float", while The Simple Development Library removes the hyphen to yield "float"; further, some opt
types are abbreviated (such as "int") while The Simple Development Library uses mostly unabbreviated names such as "integer". See the SimpleType
package for further information about types. Extended arguments are further described in the proc-ext
procedure.
The presence or absence of a regular flag in an extended procedure call argument list can be obtained via the ::Simple::Argument::information flaggiven
procedure, while the complete list of all given flags is returned by ::Simple::Argument::information givenflags
. For flags or optional arguments, ::Simple::Argument::information isdefault
returns whether an extended procedure argument actual value matches its corresponding default value. Other subcommands of the ::Simple::Argument::information
command are <description>, defaultgiven
, default
, type
and choices
.
This package encompasses the funcionality provided by the SimpleSubcommand
package, so it is recommended not to directly use the later if using the former. In fact, all procedures provided by this package work for regular procedures also, so this is the only package needed to handle regular or extended argument syntax procedures as well as regular or subcommand procedures. Nevertheless, see the SimpleDeclare
package declare-proc
command, which encompasses proc-ext
in turn.
The ::Simple::Proc::convert
pair of procedures convert between extended and Tcl canonical procedure argument formats.
::Simple::Script::append
allows to append scripts. The ::Simple::Script::Header::add
and ::Simple::Script::Trailer::add
procedures prepend a header or append a trailer to a script, respectively. Headers and trailers can be got or deleted with the ::Simple::Script::Header::get
, ::Simple::Script::Trailer::get
, ::Simple::Script::Header::delete
and ::Simple::Script::Trailer::delete
procedures.
# Install the package package require SimplePackage ::Simple::Package::require-and-install SimpleProc # Configure The Simple Development Library to store the metadata ::Simple::configure -storemetadata true # Enable arguments run-time type checking ::Simple::Proc::configure -checktype true # Create a procedure which takes an # optional flag and a required integer proc-ext { zero } { {-zero boolflag {Zero flag}} { integer integer {Integer}} } { if {$zero} { puts 0 } else { puts $integer } } # Get some info about the procedure # This displays the following: # |0 # |?-zero? integer # |Zero flag puts [::Simple::Proc::information issubcommand zero] puts [::Simple::Proc::information usage zero] puts [::Simple::Argument::information description zero -zero] # Valid calls # This displays the following: # |23 # |0 # |0 zero 23 zero 0 zero -zero 23 # Invalid call # This displays the following: # |invalid value "foo" for argument "integer" of type "integer" catch {zero foo} result puts $result # Create a couple of subcommand procedures proc-ext { command foo } { { integer integer {Integer}} { choice choice {1 2} {Choices}} } { if {$integer > $choice} { puts {The integer is greater than the choice} } else { puts {The integer is lower or equal than the choice} } } proc-ext { command bar } { {?integer? integer 1 {Integer}} } { if {[::Simple::Argument::information isdefault integer]} { puts {Default value} } else { puts {Non-default value} } } # This displays the following: # |The integer is lower or equal than the choice # |The integer is greater than the choice # |Default value # |Non-default value command foo 1 2 command foo 8 1 command bar command bar 8 # Get some info about the subcommand # This displays the following: # |1 # |foo bar puts [::Simple::Proc::information issubcommand command] puts [::Simple::Proc::information subcommands command] # Delete one of the subcommands ::Simple::Proc::delete {command bar} # Get some info about the subcommand # This displays the following: # |foo puts [::Simple::Proc::information subcommands command]
Date | Reason |
19-feb-1999 | Unreleased first version 0.1 |
23-apr-2000 | First public release, version 0.2 |
10-sep-2001 | Second public release, version 0.4 |
17-feb-2003 | Third public release, version 0.5 |
30-mar-2003 | Extra package, version 0.5.1 |
24-oct-2004 | Copy functionality deleted, version 0.5.2 |
03-dec-2004 | SimpleRegProc functionality moved here and changes to ::Simple::Proc::information subcommands, version 0.5.3 |
11-may-2005 | Bug 11 correction, version 0.5.4 |
22-jun-2005 | The Simple Development Library version 1.0 |
Copyright (C) 1999-2005, Juan C. Gil (jgil@gmv.es).
Paradigm: procedural.
Requisites: SimpleVariable 1.0
.
Description: extended format argument as {name type ?value? description}
.
Description: canonical argument as {name ?value?}
.
Type: boolean.
Value: 0.
Description: whether argument run-time type checking is performed for procedures created via the ::Simple::Proc::create
procedure in order to check whether the actual arguments match their type. This has a performance penalty which should be considered. Notice that only those procedures created via the ::Simple::Proc::create
procedure after modifying this option are affected by the change.
Type: integer.
Value: 5.
Description: if the number of arguments after the last flag in procedures created via the ::Simple::Proc::create
procedure exceedes the value of this package option, those arguments are handled via an auxiliary "after flags" procedure. The optimum value of this parameter depends on the Tcl version used. The Simple Development Library default value corresponds to the latest Tcl version. Notice that only those procedures created via the ::Simple::Proc::create
procedure after modifying this option are affected by the change.
::Simple::Proc
::Simple::Proc::Priv
::Simple::Argument
::Simple::Script
::Simple::Script::Header
::Simple::Script::Trailer
::Simple::Script::Priv
::Simple::Argument::check-type
argsSynopsis: perform runtime type checking on named arguments.
Details: see section 4.1.
::Simple::Argument::information choices
procedure argumentSynopsis: returns an extended procedure argument choices list.
Details: see section 4.2.
::Simple::Argument::information default
procedure argumentSynopsis: returns a procedure argument default value.
Details: see section 4.3.
::Simple::Argument::information defaultgiven
procedure argumentSynopsis: returns whether a procedure argument has a default value.
Details: see section 4.4.
::Simple::Argument::information description
procedure argumentSynopsis: returns an extended procedure argument description.
Details: see section 4.5.
::Simple::Argument::information flaggiven
flagSynopsis: returns whether a flag was given in an extended procedure call.
Details: see section 4.6.
::Simple::Argument::information givenflags
Synopsis: returns the flags and their parameters in an extended procedure call.
Details: see section 4.7.
::Simple::Argument::information isdefault
argumentSynopsis: returns whether an argument value is the default one.
Details: see section 4.8.
::Simple::Argument::information type
procedure argumentSynopsis: returns an extended procedure argument type.
Details: see section 4.9.
::Simple::Proc::cget
?-checktype? ?-afterflags?Synopsis: gets the package options.
Details: see section 4.10.
::Simple::Proc::configure
?-checktype extbool? ?-afterflags integer?Synopsis: configures the package options.
Details: see section 4.11.
proc-ext
?-parseflags extbool? ?-checktype extbool? procedure arguments bodySynopsis: creates a procedure with extended argument syntax.
Details: see section 4.12.
::Simple::Proc::delete
procedureSynopsis: deletes a procedure.
Details: see section 4.13.
::Simple::Proc::information access
procedureSynopsis: returns a declared procedure access mode.
Details: see section 4.14.
::Simple::Proc::information alias
procedureSynopsis: returns a declared procedure alias.
Details: see section 4.15.
::Simple::Proc::information args
procedureSynopsis: returns a procedure argument names list.
Details: see section 4.16.
::Simple::Proc::information arguments
procedureSynopsis: returns a procedure argument list.
Details: see section 4.17.
::Simple::Proc::information body
procedureSynopsis: returns a procedure body.
Details: see section 4.18.
::Simple::Proc::information caller
?levels?Synopsis: returns the caller procedure name.
Details: see section 4.19.
::Simple::Proc::information checktype
procedureSynopsis: returns whether a procedure performs argument type checking.
Details: see section 4.20.
::Simple::Proc::information exists
procedureSynopsis: returns whether a procedure exists.
Details: see section 4.21.
::Simple::Proc::information isextended
procedureSynopsis: returns whether a procedure is an extended procedure.
Details: see section 4.22.
::Simple::Proc::information issubcommand
procedureSynopsis: returns whether a procedure is a base command procedure.
Details: see section 4.23.
::Simple::Proc::information metadata
procedureSynopsis: returns a declared procedure metadata.
Details: see section 4.24.
::Simple::Proc::information parseflags
procedureSynopsis: returns whether a procedure has flag parsing enabled.
Details: see section 4.25.
::Simple::Proc::information runtimeparsing
procedureSynopsis: returns whether a procedure run-time parses its arguments.
Details: see section 4.26.
::Simple::Proc::information subcommands
commandSynopsis: returns a base command procedure subcommand list.
Details: see section 4.27.
::Simple::Proc::information usage
procedureSynopsis: returns a procedure argument usage string.
Details: see section 4.28.
::Simple::Proc::move
sourceProcedure targetProcedureSynopsis: renames a procedure.
Details: see section 4.29.
::Simple::Proc::resolve-alias
procedureSynopsis: resolves command aliases.
Details: see section 4.30.
::Simple::Script::Header::add
scriptName tag priority headerSynopsis: prepends a header to a script.
Details: see section 4.31.
::Simple::Script::Header::delete
scriptName ?pattern?Synopsis: deletes headers from a script.
Details: see section 4.32.
::Simple::Script::Header::get
script ?pattern?Synopsis: gets headers from a script.
Details: see section 4.33.
::Simple::Script::Trailer::add
scriptName tag priority trailerSynopsis: appends a trailer to a script.
Details: see section 4.34.
::Simple::Script::Trailer::delete
scriptName ?pattern?Synopsis: deletes trailers from a script.
Details: see section 4.35.
::Simple::Script::Trailer::get
script ?pattern?Synopsis: gets trailers from a script.
Details: see section 4.36.
::Simple::Script::append
scriptName scriptToAppendSynopsis: appends a non-empty script to another one.
Details: see section 4.37.
::Simple::Proc::NON-EXISTING-NAMESPACE
Message: can't create procedure "procedure": unknown namespace.
Explanation: the extended procedure procedure could not be created because the namespace does not exist.
Corrective action: use namespace eval
to create the namespace.
::Simple::Proc::TYPE-CHECKING-AND-NO-PARSE-FLAGS
Message: can not have "-parseflags false" and argument run-time type checking.
Explanation: a procedure declaration failed because argument run-time type checking was enabled and flag parsing disabled.
Corrective action: either disable argument run-time type checking or enable flag parsing.
::Simple::Proc::ARGS-MUST-BE-LAST
Message: "args" must be the last argument.
Explanation: a procedure declaration failed because an argument named "args" was supplied not the last in the list.
::Simple::Proc::NON-OPT-AFTER-OPT
Message: non-optional argument "argument" after at least one optional argument.
Explanation: a procedure declaration failed because the non-optional argument argument was supplied after an optional argument.
Corrective action: all arguments following an optional one must be either explicitly optional or the special argument "args" which is implictly optional.
::Simple::Proc::DEFAULT-NOT-ALLOWED
Message: can not have a default value for option or argument "option or argument name" of type "type".
Explanation: a procedure or option declaration failed because a default value was supplied for an option or argument which can not have it.
Corrective action: default values must be supplied for procedure optional arguments and for flags or options whose type is not "boolflag", and only for those.
::Simple::Proc::ARGS-NOT-ALLOWED
Message: "args" is not allowed if flag parsing is disabled.
Explanation: a procedure declaration failed because an argument named "args" was supplied but flag parsing is disabled.
Corrective action: either remove the "args" argument or enable flags parsing.
::Simple::Proc::ARGS-LIST-OR-ANY
Message: "args" must be of type "list" or "any".
Explanation: a procedure declaration failed because an argument named "args" was supplied with a type other than "list" or "any".
::Simple::Proc::NO-FLAG-PARSING-AND-NO-FLAGS
Message: flag parsing disabled but no flags given.
Explanation: a procedure declaration failed because flag parsing was diabled but no flags were given in the argument list.
Corrective action: enable flag parsing.
::Simple::Proc::NO-PARAM-FOR-FLAG
Message: no parameter given for flag "flag" to "procedure".
Explanation: a call to the procedure procedure failed because no parameter was supplied for the flag flag.
Corrective action: supply a parameter for the flag.
::Simple::Proc::CANT-BETWEEN-SUBCO-AND-NO-SUBCO
Message: can't copy or rename [non-]subcommand "name 1" to [non-]subcommand "name 2".
Explanation: it is not allowed to copy or rename a non-subcommand to a subcommand or viceversa.
::Simple::Proc::NON-EXISTING-PROCEDURE
Message: "procedure" isn't a procedure, an extended procedure or a declared procedure.
Explanation: procedure is not a procedure, an extended procedure or a declared procedure.
Corrective action: provide a valid procedure name.
::Simple::Proc::NON-EXISTING-ARGUMENT
Message: procedure "procedure" doesn't have an argument "argument".
Explanation: procedure procedure does not have an argument named argument.
Corrective action: provide an argument from the procedure argument list.
::Simple::Proc::NO-TYPE-CHOICE
Message: argument "argument" from procedure "procedure" is not of type "choice" nor "choice-list".
Explanation: the extended procedure procedure argument argument type is not "choice" nor "choice-list".
::Simple::Proc::CANT-BE-CALLED-FROM-TOPLEVEL
Message: "procedure" can't be called from the top level.
Explanation: it makes no sense to call procedure procedure from the top level.
Corrective action: call the procedure from a level other than the top one.
::Simple::Script::DUPLICATED-TAG
Message: duplicated header or trailer with tag "tag" in script "script".
Explanation: script script already contains a header or trailer with tag tag.
Corrective action: use ::Simple::Script::Header::delete
or ::Simple::Script::Trailer::delete
to delete the header with that tag or use another tag.
::Simple::Proc::VALUE-REQUIRED
Message: a value is required for optional or flag argument "optional or flag argument name".
Explanation: optional or flag argument optional or flag argument name requires a value, but no value was supplied.
Corrective action: supply a value for the optional or flag argument.
::Simple::Proc::ARRAY-NOT-ALLOWED
Message: derived array type "type" not allowed for argument or option "argument or option name".
Explanation: a derived array type type has been used for argument or option argument or option name but that is not allowed.
Corrective action: for arguments, a derived array type can be emulated using upvar
.
::Simple::Proc::OPTIONAL-FLAG
Message: cannot have an explicit optional flag "flag".
Explanation: flag flag was explicitly stated as optional while all flags are implicitly optional.
Corrective action: remove the question marks around the flag name.
For the sake of performance, this package does not implement some of the more esoteric features of the opt
package such as argument names abbreviation, type guessing, completion of incomplete arguments or out of order flags (this last feature might be added in a future revision of the package).
For procedures with flags and a small number of arguments SimpleProc
is about 20 times faster than the opt
package, or 4 times if run-time type checking is enabled (notice that opt
always checks the type of its arguments).
Also, several tricks are applied to improve performance (see the details section of the ::Simple::Proc::create
procedure) which result in typical procedures (those which do not require argument run-time type checking and have no flags in the argument list) behaving identically to regular Tcl procedures (no run-time parsing is required).
For a ten non-flag arguments procedure, opt 0.4.4.1
requires 2810 microseconds per call (Tcl 8.4.9, 1.0 GHz Pentium III Mobile, Linux Red Hat 7.3) while SimpleProc
uses a mere 3 or 740 microseconds when run-time type checking is disabled or enabled, respectively; that means performance improvement factors of 936 or 3.8, respectively. For a ten flag arguments procedure the figures are 2924 and 188 microseconds, a factor of 16.6. For a procedure with no arguments the figures are 90 and 2, a factor of 45. Even for procedures with flags, their parsing can be delegated to the user so, again, no overhead is introduced if desired.
The argument list internal representation of each extended procedure is stored in an element of the %ProcData% array in the procedure namespace whose index is %ArgInternal%,<unqualified procedure name>. This array element is a list with the following elements:
0 | whether the argument is a flag |
1 | whether the argument has a default value |
2 | argument name |
3 | argument default value |
4 | argument type |
5 | argument choices (empty if type is not "choice" nor derived from it) |
6 | argument description |
The argument names list of each extended procedure argument list is stored in an element of the %ProcData% array in the procedure namespace whose index is %ArgNames%,unqualified procedure name.
The indices of the first and last flags in the argument list of each extended procedure argument is stored in an element of the %ProcData% array in the procedure namespace whose index is %FlagsIndices%,unqualified procedure name.
Whether the flag parsing is enabled or has been delegated to the user for each extended procedure is stored in an element of the %ProcData% array in the procedure namespace whose index is %ParseFlags%,unqualified procedure name.
The procedure access mode is stored in an element of the %ProcData% array in the procedure namespace whose index is %Access%,unqualified procedure name.
The procedure alias is stored in an element of the %ProcData% array in the procedure namespace whose index is %Alias%,unqualified procedure name.
The procedure metadata is stored in an element of the %ProcData% array in the procedure namespace whose index is %Metadata%,unqualified procedure name.
This package is optimized for speed and not for maintenability. In particular the run-time parsing of the argument list is done by one of two different private procedures (::Simple::Proc::Priv::parse-arguments
and ::Simple::Proc::Priv::parse-arguments-checktype
) depending on whether run-time type checking is enabled or not, even though they share most of the code.
Support out of order flags.
Allow derived arrary types as extended arguments.
It might be useful to have a way to enable and disable -checktype for existing procedures.
Provide a package option or flag to proc-ext
to complain on bad flags throwing a ::Simple::BAD-FLAG
error. Currently a bad flag is assumed to be a non-flag parameter.
Implement a mechanism to pass arguments by reference. This could sit on top of a new procedure named ::Simple::Argument::upvar
which performs the upvar
. It should have an -array flag which specifies whether the entity being linked via upvar
is an array or a regular variable. It should also have an -exists (or -force) flag which, if given, asserts the array/value does exists. Independently on whether -exists is given or not, if the linked entity does exists we should assert that it is an array or a regular variable, as directed by -array being given or not.
::Simple::Argument::check-type
argsSynopsis: perform runtime type checking on named arguments.
Access mode: public.
Keywords: argument and type.
Performs runtime type checking of specific arguments for the calling procedure when runtime type checking is turned off. If runtime type checking is turned on for the calling procedure, this procedure does nothing.
This procedure is useful to force run-time type checking for a subset of arguments even when run-time type checking is explicitly turned off.
# Create a procedure with runtime type checking turned off # but that explicitly checks the type of ''arg2'' proc-ext -checktype false name { { arg1 integer {First argument}} { arg2 choice {A B} {Second argument}} } { ::Simple::Argument::check-type arg2 } # Invoke the command with non-conforming arguments. Notice that the # error refers to ''arg2'' because ''arg1'' is not being type checked. # This throws following error: # |invalid value "C" for argument "arg2" of type "choice": must be A or B name foo C
Arguments:
Argument | Type | Default value/ choices | Description |
args | list | (n/a) | List of argument names |
Returns: whether runtime type checking was performed.
This procedure returns 1 even if there are no arguments to be checked.
::Simple::Argument::information choices
procedure argumentSynopsis: returns an extended procedure argument choices list.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
argument | unqualifiedname | (n/a) | Argument name |
Returns: the extended procedure argument choices list.
::Simple::Argument::information default
procedure argumentSynopsis: returns a procedure argument default value.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
argument | unqualifiedname | (n/a) | Argument name |
Returns: whether the procedure argument has a default value.
::Simple::Argument::information defaultgiven
procedure argumentSynopsis: returns whether a procedure argument has a default value.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
argument | unqualifiedname | (n/a) | Argument name |
Returns: whether the procedure argument has a default value.
::Simple::Argument::information description
procedure argumentSynopsis: returns an extended procedure argument description.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
argument | unqualifiedname | (n/a) | Argument name |
Returns: the extended procedure argument desription.
::Simple::Argument::information flaggiven
flagSynopsis: returns whether a flag was given in an extended procedure call.
Access mode: public.
Keywords: procedure, argument and flag.
# A procedure with a single flag argument which echoes its value # informing on whether that value is the default or was given in the # argument list proc-ext name { {-flag string theflag {A flag (requires parameter)}} } { puts -nonewline "flag = <$flag> " if {[::Simple::Argument::information flaggiven -flag]} { puts "(flag given)" } else { puts "(default value)" } }
Arguments:
Argument | Type | Default value/ choices | Description |
flag | flag | (n/a) | Flag name |
Returns: whether the flag was given in the actual argument list.
Limitations:
This procedure must be called from another procedure.
The ::Simple::Argument::information givenflags
procedure.
The ::Simple::Priv::flag-given
procedure.
The ::Simple::Option::information usage
procedure.
::Simple::Argument::information givenflags
Synopsis: returns the flags and their parameters in an extended procedure call.
Access mode: public.
Keywords: procedure, argument and flag.
This procedure returns the list of flags and their parameters given in an extended procedure call. The format of the returned list is suitable to be given as argument to the array get
command: the array indices would be the flags and the array values their parameters.
Notice that for boolean flags (type "boolflag") the value is always 1.
Arguments: none.
Returns: the list of flags and their parameters given in the actual argument list.
Limitations:
This procedure must be called from another procedure.
The ::Simple::Argument::information flaggiven
procedure.
The ::Simple::Priv::flag-given
procedure.
The ::Simple::Option::information usage
procedure.
::Simple::Argument::information isdefault
argumentSynopsis: returns whether an argument value is the default one.
Access mode: public.
Keywords: procedure, argument and default value.
For flags or optional arguments, this procedure returns whether its actual value matches its corresponding default value. For other arguments the procedure returns always false.
# A procedure with an optional argument whose default value # is rather estrange, value which is used to check whether # the argument was given in the actual argument list proc-ext name { {?argument? string %DEFAULT% {Optional argument}} } { if {[::Simple::Argument::information isdefault argument]} { puts {argument not given} } else { puts "argument given = $argument" } }
Arguments:
Argument | Type | Default value/ choices | Description |
argument | unqualifiedname | (n/a) | Argument name |
Returns: whether the argument has a default value and it matches its actual value.
Limitations:
This procedure must be called from another procedure.
The ::Simple::Option::information isdefault
procedure.
::Simple::Argument::information type
procedure argumentSynopsis: returns an extended procedure argument type.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
argument | unqualifiedname | (n/a) | Argument name |
Returns: the extended procedure argument type.
::Simple::Proc::cget
?-checktype? ?-afterflags?Synopsis: gets the package options.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
-checktype | boolflag | (n/a) | Gets whether to perform run-time type checking of the procedures arguments |
-afterflags | boolflag | (n/a) | Gets the minimum number of arguments after the last flag for a procedure in order for those to be handled with an auxiliary "after flags" procedure |
Returns: the requested option value or the whole list of options if none specified.
::Simple::Proc::configure
?-checktype extbool? ?-afterflags integer?Synopsis: configures the package options.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
?-checktype? | extbool | false | Whether to perform run-time type checking of the procedures arguments |
?-afterflags? | integer | 5 | Minimum number of arguments after the last flag for a procedure in order for those to be handled with an auxiliary "after flags" procedure |
Returns: the empty string.
proc-ext
?-parseflags extbool? ?-checktype extbool? procedure arguments body(Alias for ::Simple::Proc::create
).
Synopsis: creates a procedure with extended argument syntax.
Access mode: public.
Keywords: procedure, argument, type and flag.
This procedure acts as an interface to the proc
command to create other procedures allowing a richer syntax for their arguments. Upon creation of a new procedure, its extended format argument list is parsed and converted into a canonical argument list (in which each argument has the format {name ?defaultValue?}
) which is used to actually create the procedure via the proc
command. If the argument list contains one or more flags, or if run-time type checking is requested, the procedure body is instrumented to add run-time handling of the argument list.
If the procedure name is two words, a subcommand procedure similar to that created via the SimpleSubcommand
package proc-sub
procedure is created, but with extended argument syntax. It is thus not required to use proc-sub
when using this package.
Extended syntax arguments are of the form {name type ?value? description}
Arguments whose name starts by a hyphen are flags. The presence of flags in the procedure call actual argument list is optional but.
Flags whose type is boolflag are boolean flags and do not require a parameter. For each boolean flag in the argument list, a variable is created in the procedure body with the same name as the flag (excluding the hyphen) and whose value is true or false (1 or 0) depending on whether the flag is given or not in the procedure call actual argument list.
Flags whose type is not boolflag are regular flags and require a parameter; the flag type is the expected parameter type. For each regular flag in the argument list, a variable is created in the procedure body with the same name as the flag (excluding the hyphen) and whose value is the parameter supplied after the flag, or its default value if the flag was not given in the procedure call actual argument list. The presence or absence of a regular flag in the procedure call actual argument list can be checked via the ::Simple::Argument::information flaggiven
procedure.
The list of all flags in the procedure call actual argument list together with their parameters can be obtained via the ::Simple::Argument::information givenflags
.
Arguments whose name is enclosed between question marks are optional. They differ from the flags in that they behave exactly as optional arguments to the proc
command, that is, they must appear at the end of the argument list.
As with the proc
command, the args special argument collects all remaining arguments in the actual argument list and combines them into a list which is available to the procedure body in the variable name args. If given, the args special argument must be the last one.
The argument type must be a type known by The Simple Development Library, that is, any Simple Development Library type or declared via the ::Simple::Type::declare
procedure.
An actual argument whose type is choice can only hold one of the values specified in the argument declaration default value field.
See also the boolflag type in the argument name section above.
An argument declaration can specify this field if and only if its type is choice, an optional argument, or a flag whose type is not boolflag. For arguments of type choice, this field specifies the list of allowed choices; otherwise, it corresponds to the parameter default value. For optional arguments of type choice, the default value is the first choice.
This is simply a description of the argument.
The -checktype flag allows to override the package option of the same name for the procedure being created. This option controls whether a run-time type check is performed to assess whether the arguments contents match their type. This has a performance penalty which should be considered. The overhead comes from two fronts. First, the contents of each argument must be checked. Second, it is not possible to apply the improving performance tricks described in the details section below.
The -parseflags flag allows to disable the flag parsing which is delegated to the user. This results in better performance (the procedure call is equivalent to a regular Tcl proc
procedure) at the cost of some hassle and restrictions:
The arguments from the first flag are replaced by the args special argument. It is the user responsibility to handle the args special argument to attain the desired behaviour. See the puts
clone in the examples section below.
No run-time type checking of the procedure arguments is performed. As a result, it is not allowed to supply both the -parseflags and -checktype flags. If the -checktype package option is set to true, it is not honored.
# A regular procedure proc-ext name { {-boolflag boolflag {A boolean flag}} { arg1 string {First argument}} { arg2 integer {Second argument}} { arg3 choice {foo bar} {Choice between foo and bar}} {-flag string theflag {A flag (requires parameter)}} {?arg4? string default {Optional argument}} { args list {Remaining arguments}} } { puts "-boolflag = <$boolflag>" puts "arg1 = <$arg1>" puts "arg2 = <$arg2>" puts "arg3 = <$arg3>" puts -nonewline "flag = <$flag> " if {[::Simple::Argument::information flaggiven -flag]} { puts "(flag given)" } else { puts "(default value)" } puts "arg4 = <$arg4>" puts "args = <$args>" } # A subcommand procedure for which the contents of # their arguments is run-time type checked proc-ext -checktype true {command subcommand} { {-boolflag boolflag {A boolean flag}} { arg1 string {First argument}} { arg2 integer {Second argument}} } { puts "-boolflag = <$boolflag>" puts "arg1 = <$arg1>" puts "arg2 = <$arg2>" } # A clone of puts (except in that it requires the channel) # with flag parsing delegated to the user proc-ext -parseflags false puts-clone { {-nonewline boolflag {Do not append a newline}} { channelId channel {Output channel}} { string string {String to write}} } { foreach {arg1 arg2 arg3} $args break if {![string compare $arg1 -nonewline]} { puts -nonewline $arg2 $arg3 } else { puts $arg1 $arg2 } }
Arguments:
Argument | Type | Default value/ choices | Description |
?-parseflags? | extbool | true | Whether to enable flag parsing or delegate it to the user |
?-checktype? | extbool | false | Whether to enable argument run-time type checking |
procedure | commandname | (n/a) | Procedure name |
arguments | extendedarg-list | (n/a) | Extended argument list |
body | script | (n/a) | Procedure body |
Returns: the empty string.
Effects:
Creates a command named procedure
.
May create an "after flags" command named name-%AFTER-FLAGS%
where name is the qualified name of the procedure or method being created.
If -parseflags false is given, the actual procedure which is created has the first flag and following arguments replaced by the args special argument. The procedure body is not instrumented.
If run-time type checking is enabled, the actual procedure which is created has no arguments. A call to the ::Simple::Proc::Priv::parse-arguments-checktype
procedure is added at the very beginning of the procedure body to perform the required run-time parsing and checking.
If run-time type checking is disabled, the arguments to the procedure are divided into three sets: arguments before the first flag, arguments from the first to the last flag and arguments after the last flag. The actual procedure which is created contains the first set of arguments; the second and third sets are handled by a call to the ::Simple::Proc::Priv::parse-arguments
procedure which is added at the very beginning of the procedure body to perform the required run-time parsing. If the number of arguments in the third set exceeds the -afterflags package option value, those are handled via an auxiliary "after flags" procedure instead.
If the procedure namespace does not exists it is not created. This mimics the behaviour of the proc
command.
The "after flags" procedure is named name-%AFTER-FLAGS%
where name is the qualified name of the procedure or method being created.
The list of flags given in the actual argument list is stored in a variable named %GIVEN-FLAGS% in the scope of the procedure being created.
The header added to the script body when argument run-time type checking is enabled is tagged as %PRIV%-parse-arguments or %PRIV%-parse-arguments-checktype with priority 0.
The order of the -parseflags and -checktype flags is irrelevant, but both of them must appear before the procedure name.
::Simple::Proc::delete
procedureSynopsis: deletes a procedure.
Access mode: public.
This command is similar to the rename
command when its second argument is the empty string, but works for extended procedures as well as for regular procedures.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: the empty string.
Effects:
Deletes the procedure named procedure.
No aliases for the procedure are deleted.
::Simple::Proc::information access
procedureSynopsis: returns a declared procedure access mode.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: the declared procedure access mode.
::Simple::Proc::information alias
procedureSynopsis: returns a declared procedure alias.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: the declared procedure alias.
::Simple::Proc::information args
procedureSynopsis: returns a procedure argument names list.
Access mode: public.
This command is similar to the info args
command, but works for extended procedures as well as for regular procedures.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: the procedure argument names list.
::Simple::Proc::information arguments
procedureSynopsis: returns a procedure argument list.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: the procedure argument list.
::Simple::Proc::information body
procedureSynopsis: returns a procedure body.
Access mode: public.
This command is similar to the info body
, but works for extended procedures as well as for regular procedures.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: the procedure body.
::Simple::Proc::information caller
?levels?Synopsis: returns the caller procedure name.
Access mode: public.
This procedure returns the name of a procedure up the calling stack. By default, one level up the stack is used.
Arguments:
Argument | Type | Default value/ choices | Description |
?levels? | integer | 1 | Levels up the stack in which to operate |
Returns: the caller procedure name or the empty string if not found.
::Simple::Proc::information checktype
procedureSynopsis: returns whether a procedure performs argument type checking.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: whether the procedure performs argument type checking.
This procedure returns false for non-existing or non-extended procedures.
This procedure returns true for extended procedures with no arguments.
::Simple::Proc::information exists
procedureSynopsis: returns whether a procedure exists.
Access mode: public.
This command returns whether a procedure exists, being it extended or not.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: whether the procedure exists.
::Simple::Proc::information isextended
procedureSynopsis: returns whether a procedure is an extended procedure.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: whether the extended procedure exists.
::Simple::Proc::information issubcommand
procedureSynopsis: returns whether a procedure is a base command procedure.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: whether the procedure is a base command procedure.
The ::Simple::Subcommand::information exists
procedure.
::Simple::Proc::information metadata
procedureSynopsis: returns a declared procedure metadata.
Access mode: public.
This procedure returns a list of pairs suitable to be given as argument to the array set
command. Each element is one of the flags given to declare-proc
upon procedure declaration (with no hypen), but for -arguments, -access, -alias and -body (these are obtained using specific ::Simple::Proc::information
subcommands), and the items stored by proc-ext
(parseflags and checktype; these are also obtained using specific ::Simple::Proc::information
subcommands).
Thus, the actual list of flags is: -version, -project, -synopsis, -overview, -returns, -keywords, -examples, -assumptions, -resources, -limitations, -effects, -details, -references, -remarks, -todo, -history and -copyright.
Notice that no data is returned unless The Simple Development Library -storemetadata option is set when the procedure was declared.
If a particular flag was not given in the procedure declaration, the empty string is returned as that flag contents.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: the declared procedure metadata as an item/contents pairs list.
::Simple::Proc::information parseflags
procedureSynopsis: returns whether a procedure has flag parsing enabled.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: whether the procedure has flag parsing enabled.
This procedure returns false for non-existing or non-extended procedures.
::Simple::Proc::information runtimeparsing
procedureSynopsis: returns whether a procedure run-time parses its arguments.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: whether the procedure run-time parses its arguments.
This procedure returns false for non-existing or non-extended procedures.
::Simple::Proc::information subcommands
commandSynopsis: returns a base command procedure subcommand list.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
command | name | (n/a) | Base command name |
Returns: the base command procedure subcommand list.
The ::Simple::Subcommand::information subcommands
procedure.
Procedures containing a percent sign in its name are assumed to be internal to The Simple Development Library and are excluded from the output.
::Simple::Proc::information usage
procedureSynopsis: returns a procedure argument usage string.
Access mode: public.
# A procedure with several arguments, including flags proc-ext name { { arg1 integer {First regular argument}} {-boolflag boolflag {Boolean flag}} {-flag1 string FLAG1 {First flag}} {-flag2 string FLAG2 {Second flag}} { arg2 integer {Second regular argument}} } { } # This displays the following: # |arg1 ?-boolflag? ?-flag1 string? ?-flag2 string? arg2 puts [::Simple::Proc::information usage name]
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | commandname | (n/a) | Procedure name |
Returns: the procedure argument usage string.
The ::Simple::Option::information usage
procedure.
This command works for extended procedures as well as for regular procedures.
::Simple::Proc::move
sourceProcedure targetProcedureSynopsis: renames a procedure.
Access mode: public.
This command is similar to the rename
command when its second argument is non-empty, but works for extended procedures as well as for regular procedures.
Arguments:
Argument | Type | Default value/ choices | Description |
sourceProcedure | name | (n/a) | Source procedure name |
targetProcedure | name | (n/a) | Target procedure name |
Returns: the empty string.
Effects:
Renames the procedure named sourceProcedure
to targetProcedure
.
If the target procedure namespace does not exists, it is created. This mimics the behaviour of the rename
command.
Allow to rename from subcommand to regular procedures and viceversa.
::Simple::Proc::resolve-alias
procedureSynopsis: resolves command aliases.
Access mode: public.
This procedure resolves one aliasing level for a command, if existing.
Arguments:
Argument | Type | Default value/ choices | Description |
procedure | name | (n/a) | Procedure name |
Returns: the alias resolved command name.
Limitations:
Just one aliasing level is resolved.
::Simple::Script::Header::add
scriptName tag priority headerSynopsis: prepends a header to a script.
Access mode: public.
This command prepends a header to a script.
The header is enclosed between a begin and an end of header markers formatted through the MarkerFormat package variable. Both markers contain the header tag and priority. Successive headers within a script are ordered by increasing priority which goes from 0 to 9999. If a header with the same priority as the one being prepended already exists, the original has precedence, that is, the later gets added after the former.
Arguments:
Argument | Type | Default value/ choices | Description |
scriptName | name | (n/a) | Script name |
tag | string | (n/a) | Header tag |
priority | integer | (n/a) | Header priority |
header | script | (n/a) | Header |
Returns: the empty string.
Effects:
Prepends the header to the script called scriptName
in the calling scope.
::Simple::Script::Header::delete
scriptName ?pattern?Synopsis: deletes headers from a script.
Access mode: public.
This procedure deletes script headers added by ::Simple::Script::Header::add
matching the given pattern.
Arguments:
Argument | Type | Default value/ choices | Description |
scriptName | name | (n/a) | Script name |
?pattern? | pattern | (empty string) | Pattern |
Returns: the number of deleted headers.
Effects:
Deletes the headers from the script called scriptName in the calling scope.
Use no pattern to delete all headers.
::Simple::Script::Header::get
script ?pattern?Synopsis: gets headers from a script.
Access mode: public.
This procedure returns the list of headers from a script added by ::Simple::Script::Header::add
matching the given pattern.
Arguments:
Argument | Type | Default value/ choices | Description |
script | script | (n/a) | Script |
?pattern? | pattern | (empty string) | Pattern |
Returns: the list of script headers matching the given pattern in the format {tag priority header}
.
Use no pattern to get all headers.
::Simple::Script::Trailer::add
scriptName tag priority trailerSynopsis: appends a trailer to a script.
Access mode: public.
This command appends a trailer to a script.
The trailer is enclosed between a begin and an end of trailer markers formatted through the MarkerFormat package variable. Both markers contain the trailer tag and priority. Successive trailers within a script are ordered by increasing priority which goes from 0 to 9999. If a trailer with the same priority as the one being appended already exists, the original has precedence, that is, the later gets added after the former.
Arguments:
Argument | Type | Default value/ choices | Description |
scriptName | name | (n/a) | Script name |
tag | string | (n/a) | Trailer tag |
priority | integer | (n/a) | Trailer priority |
trailer | script | (n/a) | Trailer |
Returns: the empty string.
Effects:
Appends the trailer to the script called scriptName
in the calling scope.
::Simple::Script::Trailer::delete
scriptName ?pattern?Synopsis: deletes trailers from a script.
Access mode: public.
This procedure deletes script trailers added by ::Simple::Script::Trailer::add
matching the given pattern.
Arguments:
Argument | Type | Default value/ choices | Description |
scriptName | name | (n/a) | Script name |
?pattern? | pattern | (empty string) | Pattern |
Returns: the number of deleted trailers.
Effects:
Deletes the trailers from the script called scriptName in the calling scope.
Use no pattern to delete all trailers.
::Simple::Script::Trailer::get
script ?pattern?Synopsis: gets trailers from a script.
Access mode: public.
This procedure returns the list of trailers from a script added by ::Simple::Script::Trailer::add
matching the given pattern.
Arguments:
Argument | Type | Default value/ choices | Description |
script | script | (n/a) | Script |
?pattern? | pattern | (empty string) | Pattern |
Returns: the list of script trailers matching the given pattern in the format {tag priority header}
.
Use no pattern to get all trailers.
::Simple::Script::append
scriptName scriptToAppendSynopsis: appends a non-empty script to another one.
Access mode: public.
Arguments:
Argument | Type | Default value/ choices | Description |
scriptName | name | (n/a) | Script name |
scriptToAppend | script | (n/a) | Script to append |
Returns: the empty string.
Effects:
Appends the scriptToAppend
to the script called scriptName
in the calling scope.