What does {*} do in TCL?

I used some TCL, but this design dips me.

When $ res = "Table does not exist", what will be returned?

[list [list {*}$res]] 

I know what [list [list $res]] will do, but the extra {*} just puzzles me.

Thanks for the help.

+8
list tcl
source share
3 answers

When $ res = "Table does not exist", what will be returned?

 [list [list {*}$res]] 

Well, first know that [list {*}…] is a construct that returns a list of words in ellipses (the contents of the res variable in your case). It happens that in your case, a pure effect does not mean anything, since the input string is also a well-formed list. Then it becomes the only argument of the external list , and therefore we get as a result one element element, the element of which contains a list of words Table , does , not and exist in this order, i.e. {Table does not exist} .

Extension Notes

An expanded text form list is useful for concatenating lists; the concat command does something similar (but not identical, there are some historical oddities involved in the concat ). So you would separate the two lists:

 set concatenation [list {*}$list1 {*}$list2] 

Also note that the extension (introduced in Tcl 8.5) is the true syntax, which is very unusual for Tcl. {*} changes the character of the next substitution, so that it gives a few words instead of one. While it can be dispensed with, it is actually surprisingly difficult to achieve law. For example, without it, it would be higher:

 set concatenation [eval [linsert $list1 0 list] [lrange $list2 0 end]] 

The introduction of the extension significantly reduced the number of calls to eval required for most Tcl codes (this was beneficial, since it was difficult to write correctly, many programmers were difficult to catch). This has proven particularly useful in practice with the exec command; it simplifies working with glob and auto_execok :

 exec {*}[auto_execok $someCmd] $arg1 {*}[glob *.foo] # Instead of: #eval [linsert [auto_execok $someCmd] 0 exec] [linsert [glob *.foo] 0 $arg1] # Or this _wrong_ version: #eval exec [auto_execok $someCmd] $arg1 [glob *.foo] 

Ugh. This last one had a little bend of the brain to write it in shape without expansion, although I know what I'm doing. (The wrong version is incorrect because it falls apart if $arg1 contains Tcl metacharacters ...)

+7
source share

It is documented on the Tcl syntax page. It was discussed in the Tcl wiki . It was introduced into the TIP 293 language (its predecessor was TIP 157 , where you can find out how it works).

Essentially, {*}$res will split the string into its words, separated by spaces. So, [list {*}$res] acts like [split $res] (in this case).

The end result is a single-element list, a list of words in $ res.

+5
source share

Yes, I always find that construction is also troublesome. It was called an extension, and then they cleverly renamed it {*} (very memorable!). In any case, I saw that he used to expand the list to make the contents of the list available.

See this example to understand how it works:

 % set c [list ab] ab % set d [list ef] ef % set x [list $c {*}$d] {ab} ef % set y [lindex $x 2] f % set y [lindex $x 1] e % set y [lindex $x 0] ab 
+3
source share

All Articles