<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://tcl.activestate.com/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Wed May 16 19:58:23 GMT 2012 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='195'>
<header><title>A Unique Prefix Handling Command</title><author address="mailto:peter.spjuth@space.se">Peter Spjuth</author><author address="mailto:peter.spjuth@gmail.com">Peter Spjuth</author><status type='project' state='final' tclversion="8.6" vote='after'>$Revision: 1.18 $</status><history></history><created day='2' month='may' year='2004' /><keyword>Tcl</keyword><obsoletes tip='105'/></header>
<abstract>This TIP adds a new command to support matching of strings to unique prefixes of patterns, similar to Tcl&apos;s existing subcommand-name matching or Tk&apos;s option-name matching.</abstract>
<body><section title="Rationale">
<para>When code (particularly in script libraries) wants to support shortest unique prefix matching in the manner of the Tcl core (as provided by <emph style="italic">Tcl_GetIndexFromObj</emph>) 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.</para>
<para>See also <tipref type="text" tip="105"/>, which the text above comes from.</para>
<para>Another benefit of this command is getting an error message that looks like those nice and informative error messages that built in commands have. The proposed command includes a flag to control the error behaviour.</para>
<para>Another use of prefix matching is for completion, such as a combobox showing matching alternatives, or tab completion at a prompt.</para>
<para>The former needs a list of matching elements, and the latter needs a longest common prefix. </para>
<para>These functionalities are similiar enough to group them but different enought to make it a bad idea for flags, so a prefix ensemble seems approriate for them.</para>
</section>
<section title="Proposed Change">
<para>To support this, I propose adding a <emph style="bold">::tcl::prefix</emph> ensemble with the following subcommands</para>
<itemize><item.i><para><emph style="bold">prefix</emph> <emph style="bold">match</emph> ?<emph style="bold">-exact</emph>? ?<emph style="bold">-message</emph> <emph style="italic">string</emph>? ?<emph style="bold">-error</emph> <emph style="italic">options</emph>? <emph style="italic">list</emph> <emph style="italic">string</emph></para></item.i><item.i><para><emph style="bold">prefix</emph> <emph style="bold">longest</emph> <emph style="italic">list</emph> <emph style="italic">string</emph></para></item.i><item.i><para><emph style="bold">prefix</emph> <emph style="bold">all</emph> <emph style="italic">list</emph> <emph style="italic">string</emph></para></item.i></itemize>
<para>All commands are given a list of possibilities and a string to match.</para>
<para><emph style="bold">prefix</emph> <emph style="bold">match</emph> returns the matching element in the list or an error. Basically it does what <emph style="italic">Tcl_GetIndexFromObj</emph> does except it returns a string instead of an index. The options <emph style="bold">-exact</emph> and <emph style="bold">-message</emph> corresponds to the <emph style="italic">flags</emph> and <emph style="italic">msg</emph> arguments to <emph style="italic">Tcl_GetIndexFromObj</emph>. The default value for <emph style="bold">-message</emph> is &quot;option&quot;.</para>
<para>The <emph style="bold">-error</emph> options are used when no match is found. If <emph style="bold">-error</emph> is empty, no error is generated and an empty string is returned. Otherwise the options are used as <emph style="bold">return</emph> options when generating the error message. The default corresponds to setting &quot;-level 0&quot;. Example: If <emph style="bold">-error</emph> &quot;-errorcode MyError -level 1&quot; is used, an error would be generated as [return -errorcode MyError -level 1 -code error &quot;ErrMsg&quot;].</para>
<para><emph style="bold">prefix</emph> <emph style="bold">longest</emph> returns the longest common prefix within the group that matches the given string. If there is no match, an empty string is returned.</para>
<para><emph style="bold">prefix</emph> <emph style="bold">all</emph> returns a list of all matching elements.</para>
</section>
<section title="Examples">
<para>Basic use:</para>
<verbatim><vline encoding='base64'>JSBuYW1lc3BhY2UgaW1wb3J0IDo6dGNsOjpwcmVmaXg=</vline><vline encoding='base64'>JSBwcmVmaXggbWF0Y2gge2FwYSBiZXBhIGNlcGF9IGFwYQ==</vline><vline encoding='base64'>YXBh</vline><vline encoding='base64'>JSBwcmVmaXggbWF0Y2gge2FwYSBiZXBhIGNlcGF9IGE=</vline><vline encoding='base64'>YXBh</vline><vline encoding='base64'>JSBwcmVmaXggbWF0Y2ggLWV4YWN0IHthcGEgYmVwYSBjZXBhfSBh</vline><vline encoding='base64'>YmFkIG9wdGlvbiAiYSI6IG11c3QgYmUgYXBhLCBiZXBhLCBvciBjZXBh</vline><vline encoding='base64'>JSBwcmVmaXggbWF0Y2ggLW1lc3NhZ2UgInN3aXRjaCIge2FwYSBhZGEgYmVwYSBjZXBhfSBh</vline><vline encoding='base64'>YW1iaWd1b3VzIHN3aXRjaCAiYSI6IG11c3QgYmUgYXBhLCBhZGEsIGJlcGEsIG9yIGNlcGE=</vline><vline encoding='base64'>JSBwcmVmaXggbG9uZ2VzdCB7ZmJsb2NrZWQgZmNvbmZpZ3VyZSBmY29weSBmaWxlIGZpbGVldmVudCBmbHVzaH0gZmM=</vline><vline encoding='base64'>ZmNv</vline><vline encoding='base64'>JSBwcmVmaXggYWxsIHtmYmxvY2tlZCBmY29uZmlndXJlIGZjb3B5IGZpbGUgZmlsZWV2ZW50IGZsdXNofSBmYw==</vline><vline encoding='base64'>ZmNvbmZpZ3VyZSBmY29weQ==</vline></verbatim>
<para>Simplifying option matching:</para>
<verbatim><vline encoding='base64'>YXJyYXkgc2V0IG9wdHMgey1hcGEgMSAtYmVwYSAiIiAtY2VwYSAwfQ==</vline><vline encoding='base64'>Zm9yZWFjaCB7YXJnIHZhbH0gJGFyZ3Mgew==</vline><vline encoding='base64'>ICAgIHNldCBvcHRzKFtwcmVmaXggbWF0Y2ggey1hcGEgLWJlcGEgLWNlcGF9ICRhcmddKSAkdmFs</vline><vline encoding='base64'>fQ==</vline></verbatim>
<para>Switch similar to <tipref type="text" tip="105"/>:</para>
<verbatim><vline encoding='base64'>c3dpdGNoIC0tIFtwcmVmaXggbWF0Y2gge2FwYSBiZXBhIGNlcGF9ICRhcmddIHs=</vline><vline encoding='base64'>ICAgIGFwYSAgeyB9</vline><vline encoding='base64'>ICAgIGJlcGEgeyB9</vline><vline encoding='base64'>ICAgIGNlcGEgeyB9</vline><vline encoding='base64'>fQ==</vline></verbatim>
</section>
<section title="Alternative names">
<para>Alternative names for the command that have been suggested are <emph style="bold">prefix</emph>, <emph style="bold">string prefix</emph>, <emph style="bold">string disambiguate</emph>, <emph style="bold">string prefixmatch</emph>, <emph style="bold">string matchprefix</emph> and <emph style="bold">lsearch -prefix</emph>.</para>
<para>Any name based on <emph style="italic">Tcl_GetIndexFromObj</emph> feels wrong since this command does not get any index.</para>
</section>
<section title="Discussion">
<para>Pascal Scheffers wrote:</para>
<para>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 <emph style="bold">string prefix ...</emph> or <emph style="bold">lsearch -prefix</emph>? It feels like something that could logically reside inside string handling or list handling.</para>
<para>Donal Fellows wrote:</para>
<para>Hmm, a new matching style for <emph style="bold">lsearch</emph> 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&apos;ll have to be <emph style="bold">string prefix</emph> 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.)</para>
<para>Peter Spjuth: TIP was at this point altered to suggest <emph style="bold">string disambiguate</emph> after a suggestion from Donal.</para>
<para>Donal Fellows wrote:</para>
<para>I&apos;d suggest that the <emph style="bold">-exact</emph> option be dropped, as it is trivially implementable using <emph style="bold">lsearch -exact</emph>, <emph style="bold">dict exists</emph>, <emph style="bold">info exists</emph>, <emph style="bold">switch</emph>, etc. It&apos;s also corresponding to a very rarely used flag to Tcl_GetIndexFromObj.</para>
<para>Peter Spjuth: Other ways to do <emph style="bold">-exact</emph> doesn&apos;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.</para>
<para>Voices were raised against the proposed <emph style="bold">string disambiguate</emph> and Jeff Hobbs pointed out other prefix related functions that are useful. This lead to the prefix ensemble suggestion.</para>
</section>
<section title="Reference Implementation">
<para>Partial implementation at: <url ref="https://sourceforge.net/support/tracker.php?aid=1040206"/></para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>

