Clear listing of values ​​in multiple lines

How to list values ​​in multiple lines without a backslash at the end of each line?

It is not possible to create a list in multiple lines without a backslash at the end.
For example, the following (incorrect) code:

set pets [list cat dog elephant ] 

gives an error:

 invalid command name "cat" while executing "cat" invoked from within "set pets [list cat dog elephant ]" 

It can be fixed by adding a backslash at the end of the line:

 set pets [list \ cat \ dog \ elephant \ ] 

Which is ugly and error prone.

Note:

  • I know the use of curly braces ( { and } ), but this does not allow the execution of commands, and also saves extra space characters.
  • Any other command can be used (for example, dict create ), and not just list , as in my example.

Using Tcl 8.5

+8
tcl
source share
3 answers

Tcl uses a newline (and semicolon) as a command delimiter. This is the main part of the basic syntax; you cannot get around it, so you need to use double quotes or curly braces to avoid backslash. Let's look at the possibilities (remember, list delimiters can be any non-empty whitespace sequence).

Awful, prone to list backslash errors

 set pets [list \ cat \ dog \ $elephant \ ] 

No braces with curly braces

 set pets { cat dog $elephant } 

(Note that above, $elephant is just a sequence of characters, not a read variable.)

With double quotes, replacements, but be careful!

 set pets " cat dog $elephant " 

"Be careful!" I mean, if you have a verbose member of a list, you need an internal [list …] or other quotation:

 set pets " cat dog [list $elephant] [list "elephant child"] " 

But that would be true with list + backslashes at the top.

Using subst ...

 set pets [subst { cat dog $elephant "elephant child" }] 

I could "clear this" (and avoid other potential problems) with

 set pets [list {*}[subst { cat dog [list $elephant] [list "elephant child"] }]] 

But honestly, if things get really complicated, I actually do this:

Build with a few commands

 set pets { cat dog } lappend pets $elephant "elephant child" 

It makes no sense to beat yourself above your head to use one command when two or more will do everything with fewer problems.

+10
source share

Here's a proc called lines that can do what you are looking for -

 proc lines {lines} { foreach item [uplevel [list subst -nobackslash $lines]] { lappend list $item } return $list } 

It demonstrates its use -

 set another_pet fish; set pets [lines { cat [string range hotdog 3 end] elephant $another_pet "african pygmy hedgehog" snapping\ turtle "\"henry\" the bengali tiger" }] puts $pets 

He gives out, if desired,

 cat dog elephant fish {african pygmy hedgehog} {snapping turtle} {"henry" the bengali tiger} 

Ideal here if you want to play with the plug.

+1
source share

Sometimes just creating multiple lappends for split lines can be "neat".

 set pets "" lappend pets cat lappend pets dog lappend pets elephant foreach pet $pets { puts "I like to eat ${pet}s" } 
+1
source share

All Articles