TIP #195 Version 1.5: Script Access to Tcl_GetIndexFromObj

This is not necessarily the current version of this TIP.


TIP:195
Title:Script Access to Tcl_GetIndexFromObj
Version:$Revision: 1.5 $
Author:Peter Spjuth <peter dot spjuth at space dot se>
State:Draft
Type:Project
Tcl-Version:8.5
Vote:Pending
Created:Sunday, 02 May 2004
Obsoletes:TIP #105
Keywords:Tcl

Abstract

This TIP adds a new command to support matching of strings to unique prefixes of patterns, similar to Tcl's existing subcommand-name matching or Tk's option-name matching.

Rationale

When code (particularly in script libraries) wants to support shortest unique prefix matching in the manner of the Tcl core (as provided by Tcl_GetIndexFromObj) currently either the prefixes have to be precomputed (by hand or by script) or the matching has to be done backwards. In the first case, this is either error-prone or requires an extra piece of code that has to be developed by the programmer. In the second case, the code has to be converted into a pattern which is matched against the list of supported options in some way, which is either inefficient or has hazards if the string being matched contains characters that are meaningful to the matching engine being used. Instead, it would be far nicer if we could make the core support this directly, so that script authors could just say what they mean.

See also TIP #105, which the text above comes from.

Proposed Change

To support this, I propose adding a command with the syntax

The command is given a list of possibilities and a string to match, and returns the matching element in the list or an error. Basically it does what Tcl_GetIndexFromObj does except it returns a string instead of an index. The options -exact and -message corresponds to the flags and msg arguments to Tcl_GetIndexFromObj. The default value for -message is "option".

The error message is returned so that it shows up as an error from the caller, i.e. it behaves like [return -code error -level 2].

Examples

Basic use:

% string prefix {apa bepa cepa} apa
apa
% string prefix {apa bepa cepa} a
apa
% string prefix -exact {apa bepa cepa} a
bad option "a": must be apa, bepa, or cepa
% string prefix -message "switch" {apa ada bepa cepa} a
ambiguous switch "a": must be apa, ada, bepa, or cepa

Simplifying option matching:

array set opts {-apa 1 -bepa "" -cepa 0}
foreach {arg val} $args {
    set opts([string prefix {-apa -bepa -cepa} $arg]) $val
}

Switch similar to TIP #105:

switch -- [string prefix {apa bepa cepa} $arg] {
    apa  { }
    bepa { }
    cepa { }
}

The implementation will of course be in C but this is approximately how it would be done in Tcl:

# A limited implementation example
proc prefix {table obj} {
    set msg "option"
    if {[lsearch -exact $table $obj] >= 0} {
        return $obj
    }

    set match [lsearch -glob -all -inline $table $obj*]
    if {[llength $match] == 0} {
        return -code error -level 2 "bad $msg \"$obj\", must be ..."
    }
    if {[llength $match] > 1} {
        return -code error -level 2 "ambiguous $msg \"$obj\", must be ..."
    }

    return [lindex $match 0]
}

Alternative names

Alternative names for the command that have been suggsted are prefix, tcl::prefix and lsearch -prefix.

Any name based on Tcl_GetIndexFromObj feels wrong since this command does not get any index.

Discussion

Pascal Scheffers wrote:

I am not very fond of new toplevel commands, as they have a habit of breaking existing code, or, more likely, being redefined by existing code. How about string prefix ... or lsearch -prefix? It feels like something that could logically reside inside string handling or list handling.

Donal Fellows wrote:

Hmm, a new matching style for lsearch could work (yet another option for an overly scary command!) especially in conjunction with some of the other options like -inline, but I suspect it'll have to be string prefix or something like that since then we can easily state that the behaviour is not to necessarily return the first matching element. That was what scuppered #105 after all (much to my annoyance.)

Peter Spjuth: TIP has been altered to suggest string prefix.

Donal Fellows wrote:

I'd suggest that the -exact option be dropped, as it is trivially implementable using lsearch -exact, dict exists, info exists, switch, etc. It's also corresponding to a very rarely used flag to Tcl_GetIndexFromObj.

Peter Spjuth: Other ways to do -exact doesn't give the standardized error message so it has some value for those that want that functionality. The Core uses TCL_EXACT in a few places where it makes sense so the flag can be useful.

Copyright

This document has been placed in the public domain.


Powered by TclThis is not necessarily the current version of this TIP.

TIP AutoGenerator - written by Donal K. Fellows