2
votes

In tcl, now I want to source a file with some arguments, for instance, source file arg1 arg2. I use a procedure like this

proc src {file args} {
  set argv $::argv
  set argc $::argc
  set ::argv $args
  set ::argc [llength $args]
  set code [catch {uplevel [list source $file]} return]
  set ::argv $argv
  set ::argc $argc
  return -code $code $return
}

If I do src file arg1 arg2, it works perfectly. However, I can only provide the arg1 and arg2 as one string, for instance: set string "arg1 arg2". Then my src proc will take this string as one argument. Is there any way to solve this problem?

1

1 Answers

3
votes

You want argument expansion. Tcl has special syntax for that (from 8.5 onwards):

src $file {*}$string

See that {*}? If it's first in the word, the rest of the word is parsed (as a Tcl list) into multiple words which are used.


In 8.4 and before, you had to do this instead:

eval [linsert $string 0 src $file]

Or any number of other horrible recipes. People tended to be lazy and write:

eval src $file $string

But that would blow up if $file had spaces in, or $string was formatted as anything other than a canonical list, such as:

set string {
    arg1
    arg2
}

That's a legal list. Non-canonical though, and makes the eval blow up without precautions.

We added {*} in 8.5 precisely because we were fed up with all the subtle bugs from the evals…