TCL注释列表中的项目

TCL注释列表中的项目,tcl,Tcl,是否有一种简单的方法来注释列表中的项目 set ll [list \ tom \ # dick \ # harry \ martha] puts [llength $ll] 令人恼火的是,notepad++和vim突出显示了包含martha的行,这让我误以为它们被注释掉了 我以为长度是2,但它是6-它算作单独的列表项。我有一个相当长的列表,有时我希望在没有这些项目的情况下运行脚本。我希望将原始项目保留在列表中,以便下一个修改它的人知道可用的内容,并可以相应地对项目

是否有一种简单的方法来注释列表中的项目

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

puts [llength $ll]
令人恼火的是,notepad++和vim突出显示了包含martha的行,这让我误以为它们被注释掉了

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


我能想到的唯一选择是,如果列表中的项目是a,那么跳过下一个项目。有更简单的方法吗?

请参见Tcl wiki上的脚本列表命令:

您不能注释掉这样的元素。TCL内置的注释处理只在命令名称可以开始的点上找到注释,而不是在列表命令的参数中间。或者任何其他命令,尽管有些命令采用脚本,脚本可以包含在解析脚本时解析的注释

如果您是这样构建列表的:

set myList {
    a b c
    # commented out
    d e f
}
set myList [list a b c \
    # commented out \
    d e f]
然后,在将字符串作为列表处理之前,可以对其进行后处理,从而使事情顺利进行。我在较长的脚本中经常这样做

set myList [regsub -all -line {^\s*#.*$} $myList ""]
这并不是一个完美的解决方案,因为它可能通过巧妙的手段来击败它,但对我来说效果很好

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

set myList {
    a b c
    # commented out
    d e f
}
set myList [list a b c \
    # commented out \
    d e f]
那要复杂得多!问题是,当列表写入myList时,换行符已经消失了;我能想到的唯一可行的修复方法是让源代码对整个脚本进行预处理!下面是一个方法。这并不完美;一些内省技巧可以检测出发生了什么

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
}

同样,这并不完美,但只要您在加载到实际代码之前为源代码定义此过程替换,它就很可能适合您的代码。但我只使用了第一种技术——在构建后对我放入注释的列表进行后处理,我不会将其用于短列表,因为短列表之前总是可以有注释。

为了允许在数据结构中配置内容,为了使每个项目都可用,但只能实际使用当前配置中要使用的项目,最好使用几种策略中的一种来选择要使用的项目,而不是试图让解释器为您进行选择

一种可能的方法是:

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]

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

我这样做的一个例子来自Tcl Quadcode的测试/演示运行程序。