tcl评论的奇怪行为?

时间:2015-03-07 13:26:26

标签: comments tcl

我有以下tcl文件:

proc test {} {
## proc test {} {
#      puts "test"
## }
    puts "Hallo"
}

哪个不会产生错误。

如果我现在删除评论中的括号,我会收到错误

proc test {} {
## proc test {} {
#      puts "test"
## 
    puts "Hallo"
}

为什么解释器的行为如下?部分评论是否以某种方式进行评估?

2 个答案:

答案 0 :(得分:1)

如果括号 - 也就是说,字符{ - 出现在proc中的Tcl注释中,则Tcl解析器将以您可能不期望的方式运行。 #字符不是特殊的预处理程序指令(因为注释在C / C ++中)。在Tcl中,注释很像命令。如果命令以字符#开头,则忽略该行的其余部分。 在Tcl中定义proc时,实际上是在运行proc命令,它需要三个参数:过程的名称,过程参数列表和过程体。参数列表和过程体都必须是正确形成的字符串,它们通常用括号引用。您可以在这些字符串中使用嵌套引号,但不能使用额外的开括号或不平衡的引号。因此,就proc命令而言,这是一个完全有效的声明。

proc foo { args } {
      puts "executing procedure foo"
      # comment out this code block {
           foreach a $args {
                puts "argument: $a"
           }
      }
 }

请注意,过程体是一个格式良好的Tcl字符串。所有嵌套的括号都平衡。 proc命令实际上对过程体没有任何作用。执行该过程后会发生这种情况。 当您执行foo过程时,Tcl会识别#注释命令,并忽略该行上的其余字符,包括尾随的开括号。然后它处理foreach命令,该命令需要三个参数,其中一个参数是由大括号引用的多行字符串。然后它尝试将结束括号作为命令处理,并失败:

% foo test
 invalid command name "}"

您可能一直试图注释掉一段代码,例如

 # comment out this block {
 proc foo {} {
      blah ; blah ; blah
 }
 }

但由于评论中无法匹配的大括号,这不起作用。注释掉该代码块的最彻底的方法是在每行的开头放置#。但这是很多工作。相反,如果您的块格式正确,可解析,Tcl代码,请使用if或proc命令删除代码,如下所示:

#  comment out this block using 'if'
 if 0 {
 proc foo {} {
      blah ; blah ; blah
 }
 }

#  comment out this block using 'proc'
 proc donteverrunme {} {
 proc foo {} {
      blah ; blah ; blah
 }
 }

来源:http://wiki.tcl.tk/462

答案 1 :(得分:1)

Tcl的评论是真实的评论,但它们与同时解析作为语法的其他部分,例如大括号。这意味着当我们解析你的代码时,我们也必须考虑括号计数。以下是解析器的思考方式:


“准备解析命令。”

proc test {} {

“仍在解析命令。现在正在寻找一个结束支撑。“

## proc test {} {

“仍在解析命令。现在正在寻找两个关闭的括号。“

#      puts "test"

“仍在解析命令。现在正在寻找两个关闭的括号。“

## 

“仍在解析命令。现在正在寻找两个关闭的括号。“

    puts "Hallo"

“仍在解析命令。现在正在寻找两个关闭的括号。“

}

“仍在解析命令。现在正在寻找一个结束支撑。“

“糟糕!没有更多的脚本,但仍在寻找结束。错误时间!“


解析器到了最后,它仍在寻找那个结束括号。只有在调用过程并评估过程的主体脚本时,它才会将内部#解释为注释的开头。

这样做的好处是,您可以将#用于评论之外的其他内容,例如,如果您在Tcl脚本中嵌入了一些C代码,那么#启动时预处理器指令。