整齐地列出多行的值

时间:2014-03-25 08:37:59

标签: tcl

如何在每行末尾没有反斜杠的多行中列出值?

无法在多行中创建列表而不会在末尾添加反斜杠 例如,以下(错误的)代码:

set pets [list 
    cat
    dog
    elephant
]

给出错误:

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

可以通过在行尾添加反斜杠来修复它:

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

哪个是丑陋的,容易出错。

请注意:

  • 我知道使用花括号({& }),但它不允许执行命令并且还保留多余的空白字符。
  • 可以使用任何其他命令(例如dict create),而不仅仅是我的示例中的list

使用Tcl 8.5

3 个答案:

答案 0 :(得分:14)

Tcl使用换行符(和分号)作为命令分隔符。这是基本语法的核心部分;你不能解决它所以你必须使用双引号或大括号来避免反斜杠。让我们看一下可能性(记住,列表分隔符可以是任何非空的空格序列)。

带有反斜杠的丑陋,容易出错list

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

使用大括号,无替换

set pets {
    cat
    dog
    $elephant
}

(请注意,在上面,$elephant只是一个字符序列,不是变量读取。)

使用双引号,替换但要小心!

set pets "
    cat
    dog
    $elephant
"

通过“小心!”我的意思是,如果您有一个列表的多字成员,则需要内部[list …]或其他引用:

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

但顶部的list +反斜杠也是如此。

使用subst ...

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

我可以用以下方式“清理它”(并避免其他潜在的问题):

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

但坦率地说,如果事情变得非常复杂,那么我实际上这样做:

使用多个命令构建

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

当两个或两个以上的人在处理问题较少的情况下做任何事情时,不要抨击自己头脑中使用一个命令。

答案 1 :(得分:1)

这是一个名为lines的过程,它可以做你正在寻找的东西 -

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

以下是其使用的演示 -

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

根据需要输出

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

如果你想玩叉子,那么Ideone是here

答案 2 :(得分:1)

有时只需要多次分叉就可以“整齐”。

set pets ""
lappend pets cat
lappend pets dog
lappend pets elephant

foreach pet $pets {
   puts "I like to eat ${pet}s"
}