I have viewed TIP#457 [
1] and disussions with an eye towards keeping faith with the Tao of Tcl. I've thought about this general issue, and spurred by Cyan Ogilvie's paper, I have come up with the following proposal. I think this proposal is forward compatible with existing scripts and provides for the requirements for: built-in argument pre-parsing, named parameters -ish, and passing by reference or passing arrays or call by name (obviate upvar).
I'm putting this out for discussion. I am not intending to file a TIP since I do not have an implementation nor will be attempting one. The work here might even be best handled by multiple TIP's.
Proposal:
Expand proc arglist definition to accept additional specification details for arguments. Each argument specifier list can be expanded to have additional fields. All additional fields are optional.
- Use Tk as a model to define the additional fields.
argname -- name of argument variable.
default -- Default value if actual is not specified.
optionname -- "flag" name used when specifying argument actual
by name
argtype -- Type definition
argclass -- Name to be used for possible db lookup,
or validation, or ...
flags -- Examples: NULL_OK, REQUIRED, etc.
help -- Brief textual description of argument
Boolean Int Double String Flag
Array List Dict Ref Script
Anchor Bitmap Border Color Cursor Font
Justify Pixels Relief Synonym Window
- User defined types: this could be the name of an OO class assumed to have certain methods for validation.
- The "Flag" type is an option that does not take a value. Either the option is present or it is not. A "Boolean" type is an option that takes a boolean value. "-join" in glob is a "Flag", "-gmt" in clock is a "Boolean".
- The empty type, "", is treated as a string.
- Flags
- NULL_OK -- Tcl does not have nulls, but the closest surrogate would be a variable that does not exist. To demonstrate:
proc test {
{f "" -f Font TextFont NULL_OK "Specifies override font (optional)"}
} {
if {[info exists f]} {
puts "Using font $f"
} else {
puts "Font is NULL"
}
}
- Extend the Tcl C API call Tcl_CreateObjCommand() to accept an optional args list.
Tcl_CreateObjCommandEx(interp, cmdName, proc, argsList, clientData, deleteProc)
- A shorthand for passing arrays: use () to denote an array argument. Any other syntatic sugar has a non-zero chance of breaking existing code. (note: it's not legal currently to use parentheses '()' in an argument name)
proc find_flightplan_from_position {flightplan() position()} {}
- For internationalization purposes, consider all hyphen like glyphs to be equivalent when processing options. (- MINUS Unicode: U+002D, UTF-8: 2D; – EN DASH Unicode: U+2013, UTF-8: E2 80 93; — EM DASH Unicode: U+2014, UTF-8: E2 80 94; ‑ NON-BREAKING HYPHEN Unicode: U+2011, UTF-8: E2 80 91)
Example proc with additional argument details:
proc http::register {
{proto "" -protocol "" "" REQUIRED "URL protocol prefix, e.g. https"}
{port "" -port Int "" REQUIRED "Default port for protocol"}
{command "" -command Script "" REQUIRED "Command to use to create socket"}
} {
variable urlTypes
set urlTypes([string tolower $proto]) [list $port $command]
}
bll 2016-11-27 And it would be nice if the option processing/parsing could also be called separately so that command line parameters could be parsed (from argv, from an environment variable, from a configuration file).
[Category proc args call-by-reference] |