Tcl中的变量范围和源命令

时间:2011-12-14 17:28:51

标签: variables tcl scope

我有以下两个文件: a.tcl:

set condition false
source b.tcl

b.tcl:

if {$condition} {
    puts "hello"
}

当我运行a.tcl时,它会输出“hello”。这是访问a.tcl中定义的变量的正确做法吗? b.tcl中$ condition的范围是什么?谢谢。

2 个答案:

答案 0 :(得分:2)

condition的范围是全球性的。 source命令评估在运行的上下文中从指定文件读取的脚本;在您的情况下,此上下文也是全局的,因此您的puts可以正常工作。

关于练习的问题比较复杂,因为它很大程度上取决于你的实际操作。

答案 1 :(得分:1)

source命令的工作方式非常类似于将文件读入字符串然后将其传递给eval(唯一的细微之处在于info script )。这意味着source完成的范围将是评估脚本最外层的范围,因此您可以将condition作为局部变量:

proc funkystuff {condition} {
    source b.tcl
}
funkystuff true

这将起作用(并且实际上对于Tcl的包定义脚本如何工作至关重要;它们是在存在描述包定义所在位置的局部变量$dir的上下文中进行评估的)但它可以最肯定会导致令人困惑的代码! 因此,编写脚本是一种很好的做法,这样它们内部的代码就不会对它所评估的上下文做出任何假设。最简单的方法是将脚本中的代码放在名称空间中,其中名称命名空间是完全限定的。

namespace eval ::foobar {
    # Do stuff here...
}

尝试编写在源上没有过度参数化的代码也是一件好事,而不是为你加载的代码版本保存(例如,一个用于Linux的文件,另一个用于Windows)或者你的参数是什么传递给命令。当然,你不 以这种方式工作,但它确实有助于使你的代码健壮且易于理解。

最后,用于主脚本到Tcl解释器的作用域总是在全局级别进行评估(即,在没有父作用域的::名称空间中)。