Version 45 of Command Option Parsing

Updated 2017-10-25 06:02:21 by Napier

Command Option Parsing

Napier 10/24/2017

Preface

This article is an a (largely opinionated) overview of option / argument handling in Tcl. The goal here is to take a look at a proposed solution for the universal handling of options within Tcl Commands (whether they be procs, methods, applys (lambdas), or whatever else). This proposal may not be the solution to every problem - or anyones problem for that matter. Discussion is absolutely encouraged. Suggestions will be added to the optcmds implementation behind an option for testing and comparison.

There are so many opinions on the "best way" to handle all of these topics. Due to this, the TIP's for named arguments seem to constantly be a hot topic (and at an almost complete stand still). When introduced - some will say "ahh no default values - trash", others "it needs to be all local variables", others "it needs to be an array", others "none of that is needed - it needs to be simple." So our goal here is to start to hone in on a universally (good luck) accepted solution.

optcmds package was created with the specific intent of improving the handling of options passed to the command without trying to get too fancy. These options already are not positional by nature, they allow giving a simple "switch" (-opt), as well as a "named value" (-opt value), and go along with the built-in Tcl syntax for taking options. There is really nothing new to learn, and it can be implemented with very little changes to the way we define our commands (maintaining backwards compatibility).

While the (currently) unofficial TIP provides the detailed information, this page was created to provide examples and allow discussion of various aspects of the proposal. It's pure-tcl implementation provides various options for testing different possible methods that the final solution could be implemented if accepted. You should also view the useful links section below to take a look at the other proposals for named arguments.

Keep It Simple

While the author is actually a supported of the named argument TIP implementations, they can make code hard to read and understand. The goal of the optcmds syntax is to instead keep it simple. Focus on the parts that can be improved (especially when it comes to performance) and leave the rest of the logic to the script.

To illustrate the point being made, below is an example of the definition for named arguments. If you are not familiar with the specification & syntax itself, this will likely serve as a great example. Can you tell exactly what this command is expecting and how to call it? Sure, documentation will help - but should it be required to find some external documentation when working with your source? This is even a simple example with a single argument. It can also get much more complex with more arguments as they are needed.

proc p { { level -name lvl -switch {{quiet 0} {verbose 9}} } {
     list level $level
}

What about when we need more than one argument?! While it is the authors personal opinion here, it just becomes hard to understand the intent of the argument definition without either being the author of the code and/or spending time with the documentation to grasp what is going on. Sure, its awesome to save a few lines of code in the body of the proc and use our little "arg scripting language" to do some logic, but it just seems like its trying to do too much.

proc p { { level -name lvl -switch {{quiet 0} {verbose 9}} { inc -name i -upvar 1 -required 1 } { v -name var } a } {
     list level $level
}

optcmds

The author will be the first to admit there is no perfect solution (and optcmds absolutely is not the perfect solution either).

Lets say you wanted to provide a command which models its option/argument handling after the built-in tcl commands. Lets mirror a well-known built-in commands argument handling. The focus here is not "lets find the most efficient and best way to parse this." Lets simply illustrate the amount of logic that can be necessary to properly parse options. We will be looking at the glob command.

glob defines various switches/options. Some of these take a value and others are simple toggles:

glob ?switches...? pattern ?pattern ...?

Supported switches are:

-directory directory
-join
-nocomplain
-path pathPrefix
-tails
-types typeList
--

Useful Links & Information