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的测试/演示运行程序。