TCL评论列表中的项目

时间:2018-03-30 08:58:09

标签: tcl

是否有一种简单的方法来评论列表中的项目?

set ll [list \
    tom \
#    dick \
#    harry \
    martha]

puts [llength $ll]

非常令人讨厌的记事本++和vim用#突出显示这些行,以及包含martha的行,让我误以为它们被注释掉了。

我认为长度为2但它是6 - 它将#计为单独的列表项。我有一个相当长的列表,有时我想运行没有这些项目的脚本。我希望保留列表中的原始项目,以便修改它的下一个人知道可用的内容,并可以相应地评论/取消注释项目。

我能想到的唯一选择是列表中的项目是否为#,然后跳过下一项。有没有更简单的方法呢?

3 个答案:

答案 0 :(得分:1)

请参阅Tcl wiki上的Scripted List命令:http://wiki.tcl.tk/scripted+list

答案 1 :(得分:1)

你无法评论出那样的元素。 Tcl的内置注释处理只能在命令名称可以启动的位置找到注释,并且不在list命令的参数中间。或者任何其他命令(尽管某些命令采用脚本,其中可以包含在解析脚本时解析的注释)。

如果您正在构建如下列表:

set myList {
    a b c
    # commented out
    d e f
}

然后,可以通过对该字符串进行后处理来使其工作,然后将其作为列表处理。我在较长的剧本中做了相当多的事。

set myList [regsub -all -line {^\s*#.*$} $myList ""]

这不是一个完美的解决方案,因为它可以通过狡猾来打败它,但它对我来说很好。

但是,在处理列表构造时是这样的:

set myList [list a b c \
    # commented out \
    d e f]

这要复杂得多!问题是,当列表写入myList时,换行符已经消失;我能想到的唯一可行的解​​决方法是让source预处理整个脚本!下面是一种方法。 (这不是完美的;一些内省技术可以检测到发生了什么。)

proc source args {
    # Argument parsing; the full works
    set enc [encoding system]
    if {[llength $args] > 1 && [lindex $args 0] eq "-encoding"} {
        set enc [lindex $args 1]
        set args [lrange $args 2 end]
    }
    if {[llength $args] != 1} {
        return -code error \
            "wrong # args: should be \"source ?-encoding name? fileName\""
    }
    set fileName [lindex $args 0]

    # Read in the script
    set f [open $fileName]
    fconfigure $f -encoding $enc -translation auto -eofchar \x1a
    set script [read $f]
    close $f

    # Pre-process the script; note that we're more careful with backslashes here
    set script [regsub -all -line {^\s*#.*([\\]?)$} $script {\1}]

    # Evaluate the script in the caller while setting [info script]
    info script $fileName
    uplevel 1 $script
}

同样,这并不完美,但只要您在加载实际代码之前为source定义此过程替换,它就可能适用于您的代码。但我只是使用第一种技术 - 对构建之后中的注释列表进行后处理 - 相反,我不会将它用于短列表(因为那些总是有评论)之前代替。)

答案 2 :(得分:1)

要允许数据结构中的可配置内容,以便您可以让每个项目都可用,但实际上只使用您要在当前配置中使用的项目,最好使用多种策略之一来选择项目使用,而不是试图让翻译为你做选择。

一种可能的方法:

lmap item [concat {*}{
    tom
    dick
    #harry
    #martha
}] {if {[string match #* $item]} {
        continue
    } else {
        set item
    }}

在Tcl中,只有命令可以被注释掉,即使您尝试这样做也会有陷阱。

如果在该位置预期命令的名称,则#句法标记仅被解释为注释的开头。在其他任何地方,它只是一个普通的角色(即使语法突出显然经常将其误认为是评论)。

# ceci n'est pas une 'comment'
upvar #0 foo bar

暂时从列表中删除项目,例如为了调试目的,最好只重做定义:

set ll [list \
    tom \
    dick \
    harry \
    martha]

set ll [list \
    tom \
    martha]

将使用最后一个定义。如果更改不限于一个编辑会话,则可能会造成混淆。为避免这种情况,保存原始代码并完全重写正在使用的代码可能是一个不错的选择。