4

Specifically lets say i create a list with :

for {set i 0} {$i < $val(recv)} {incr i} {
    lappend bwList "videoBW_($i).tr"
    close $videoBW_($i)
}

and then i want to give that list as an argument of multiple files with

exec xgraph $bwList -geometry 800x400  &

It will give me the error:
Warning: cannot open file `videoBW_(0).tr videoBW_(1).tr videoBW_(2).tr'

Because tcl reads the whole list as one string instead of multiple strings. Is there a way to read the list as multiple strings ?

EDIT :

The solution for tcl8.4 is the one Brian Fenton provided. but by changing set exec_call {xgraph $bwList -geometry 800x400} to set exec_call "xgraph $bwList -geometry 800x400"

Basically if you only add eval in front of exec it does the job .

  eval exec xgraph $bwList -geometry 800x400  &

Fot tcl 8.5 Bryan Oakley provided a more elegant solution.

4 Answers 4

4

If you are using tcl 8.5 or later you can do:

exec xgraph {*}$bwList -geometry 800x400  &

{*} is called the expansion operator. It expands lists into individual elements before the statement is executed.

See section 5 of the Tcl man page for the definitive explanation.

Sign up to request clarification or add additional context in comments.

1 Comment

i am working on tcl 8.4 but this seems a more elegant solution for tcl8.5 or later so i voted up.
2

In 8.5 and later:

exec xgraph {*}$bwList -geometry 800x400 &

In 8.4 and before:

eval exec xgraph $bwList -geometry 800x400 &
# Or this more formally-correct version...
# eval [list exec xgraph] [lrange $bwList 0 end] [list -geometry 800x400 &]

As you can see, the 8.5 expansion syntax helps a lot, and that's particularly true as you go from simple experimentation to production code (e.g., if you're adding a label argument with spaces in to that command line; the expansion version will just handle it correctly, but with the old version you'll get into having to quote everything up properly, which you can see is very messy above).

1 Comment

Even though the other answers are also correct this is the most complete one and i am marking it so that other people can find it faster.
2

I don't fully understand what you mean by "multiple strings". It would help me if you showed what the final call to xgraph should look like. I thought with xgraph that the files came at the end (i.e. after the -geometry 800x400)?

Anyway what might help is using eval instead of a direct call to exec.

set exec_call {xgraph $bwList -geometry 800x400}
set caught [catch {eval exec $exec_call} result]
if { $caught } {
 #handle the error - it is stored in $result
} else {
 #handle the success
}

2 Comments

ok , the final call to xgraph should look like : exec xgraph videoBW_(0).tr videoBW_(1).tr -geometry 800x400 & more specifically so you understand what i am saying : exec xgraph "videoBW_(0).tr" "videoBW_(1).tr" -geometry 800x400 & right now it is : exec xgraph "videoBW_(0).tr videoBW_(1).tr" -geometry 800x400 & which i don't want Quote : I thought with xgraph that the files came at the end (i.e. after the -geometry 800x400)? It doesn't make a difference.
set exec_call {xgraph $bwList -geometry 800x400} is wrong because it does not evaluate $bwList it should be: set exec_call "xgraph $bwList -geometry 800x400 . If you edit that in your answer it will be correct
2

For Tcl 8.4 I'd do it like this:

set cmd [concat [list exec xgraph] $bwList]
lappend cmd -geometry 800x400

2 Comments

One of the canonical methods to ensure list-ness is: set cmd [linsert $bwList 0 exec xgraph]; lappend cmd ...
Correct. I prefer [concat] in this case because it looks more naturally with regard to the ordering of the elements of the resulting list. I mean, exec xgraph goes before $bwList in the code, so it looks less twisted compared to [linsert].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.