nxproc

nxproc is a Tcl extension providing named-argument input for user-defined procedures like many built-in Tcl commands. In most cases nxproc is a drop-in replacement for proc while offering additional capabilities. For TclOO users, equivalent functionality is supplied by the extension's nxmethod and nxconstructor commands.

Availability:

Fossil repo:https://thinairarts.com/fossil/procx/index
Direct download: https://thinairarts.com/fossil/procx/download
Documentation:https://thinairarts.com/fossil/procx/file?name=doc/nxproc-doc.html&ci=tip

Archives contains full source as well as ready-to-use Linux and Windows binaries for Tcl 8.7 and 9.0. (The extension can run under 8.6.11+, but requires compiling for 8.6. To use the test directory under 8.6, source oonxtest-8.6.tcl instead of oonxtest.tcl.)

Installation:

On Windows and Linux, copy the appropriate nxproc1.0 directory to the installed Tcl's extention directory (e.g., /usr/local/lib, etc.). Compiling and installing from source is described in the project documentation.

Features and usage:

Command arguments:

nxproc syntax is similar to standard proc. The main difference is how arguments are specified. nxproc recognizes 4 kinds of arguments:

  • positional arguments
  • named arguments
  • nxargs, similar to args in proc
  • nxunknown, another args-like variable

Positional arguments are handled much like in proc (default values included). These arguments must come before any named or unknown parameters.

Named arguments can be entered in any order. Since they always have a default value, supplying named arguments is optional. A typical use case is a procedure implementing configuration settings.

In addition, nxproc commands enforce a limited form of argument type checking at creation and runtime. Types include string, numeric, boolean and enumerated, indicated by "type designators".

Type Designator (abbr) Value Example
string str (s) string (default) -arg0 thevalue or -arg0 s thevalue
number num (n) number -arg1 101 or -arg1 n 101
boolean bool (b) 0,1 -arg2 b 0
enumerated enum (e) valid Tcl list -arg3 e {abc cde efg}

Examples:

    package require nxproc

    # Boolean
    nxproc myproc {-flag1 b 0} {
        # designator is case insensitive
        # b, B, bool, Bool, BOOL, etc. are all valid 
        puts [expr {$flag1 ? "True" : "False"}]
    }
    myproc -flag1   
    # -> True 
    # "Bare" bool arguments, i.e., no value given, toggle default value. Here, 0 -> 1
    myproc -flag1 0 
    # -> False
    # runtime type check
    myproc -flag1 abc 
    # -> Error: 'abc' is not boolean

    # Enumerated
    nxproc myproc {-animal e {cat dog elephant}} {
        puts "Animal selected is: $animal"
    }
    myproc -animal   ;# -> cat (default value is first item in enum list)
    myproc -animal elephant ;# -> elephant
    # runtime type check
    myproc -animal bear 
    # -> Error: 'bear' is not a member of enum 'animal'

Because their types are inferred, designators aren't normally required for str and num arguments. However, enum and bool types do require designators to disambiguate enum from string and bool from numeric values.

nxargs is like the "args" variable in proc, except that "nxargs" isn't appended to the nxproc agument list. Rather, at runtime using "-->" at end of input arguments puts whatever follows into the "nxargs" variable accessible in the procedure body. (The symbols -->, --, -> are equivalent and signal end of command line arguments.) All subsequent input is collected into a list and assigned to the nxargs variable.

    # nxargs
    # create a command
    nxproc myproc {-str1 "my input"} {
        puts "str1=$str1  nxargs=$nxargs"
    }
    # call command
    # "-->" marks end of regular arguments
    myproc -str1 "xyz" --> whatever you like
    # -> str1=xyz  nxargs=whatever you like

nxunknown is another args-like variable, active when "**" is included in the argument list. When ** is present, all unknown input entered on the command line is collected in the nxunknown variable also accessible in the procedure body. Using **, no error is issued due to bad input. Note that ** must come after any positional arguments. It can be placed before or between named argument/value sets or at the end of the argument list.

    # nxunknown
    # create command
    nxproc myproc {-str1 "my input" **} {
        puts "str1=$str1  nxunknown==..$nxunknown.."
    }
    # call command
    myproc -str1 abcde other -stuff, etc.
    # -> str1=abcde  nxunknown==..other -stuff, etc...

Object-oriented commands

TclOO compatible commands include nxmethod and nxconstructor. These have all the features of nxproc but built for TclOO. Basically syntax is identical to standard method and constructor syntax, except for nx- specific features:

    oo::class create Timer {
        nxconstructor {-iters 100000} { ... }
        nxmethod time {body} { ... }
        ...
    }

Case-insensitive variants

All three nx... commands are also supplied as -ci commands. These -ci variants allow command-line option names to be entered without regard to case. This applies only to "-argname" inputs defined at command creation time. It does not affect the names of variables available in the procedure body (which are always exactly the name supplied in the argument list, minus the leading dash).

    nxproc-ci myproc {-str1 abc} {
        puts "\$str1 == $str1"
    }
    myproc -str1 yes ;# -> $str1 == yes
    myproc -STR1 yes ;# -> $str1 == yes
    myproc -Str1 yes ;# -> $str1 == yes

Other nxproc features

Runtime dislay of arguments and defaults

Calling an nxproc-generated command with the argument "-?" or "-opt" prints its arguments and their default values to the terminal.

    nxproc myproc {-str1 "mystring" -num1 101 -flag1 b 0 -enum1 e {abc cde efg}} {
        puts "$str1 $num1 $flag1 $enum1"
    }
    myproc
    # -> mystring 101 0 abc
    myproc -?
    _____ bool ____
       flag1: 0
    _____ str _____
        str1: mystring
    _____ num _____
        num1: 101
    _____ enum ____
       enum1: abc cde efg

The dtype command

When called within a generated command, dtype prints the assigned type of a variable.

    nxproc myproc {-n 223 -s "a short string"} {
        puts "n==$n, type is '[dtype n]'"
    }
    # -> n==223, type is 'num'

Compiling from source:

While the downloaded archive contains ready-to-use Windows/Linux binaries, compiling from source is necessary for other platforms or when modifications to source are made. Please see project documentation for more complete information.

Note: nxproc uses the configdef configuration utility to generate makefiles. Basic use involves supplying Tcl source and installation directories when calling config (application from the configdef package), or alternatively, editing config.def to have the correct values. config uses the per directory config.def file to generate a Makefile which is then processed with make as usual.

Full documentation of configdef is provided in the configdef repository.

Documentation:

The project documentation has full information on the above topics.

2024-01-29 jrapdx