我有以下两个文件: a.tcl:
set condition false
source b.tcl
b.tcl:
if {$condition} {
puts "hello"
}
当我运行a.tcl时,它会输出“hello”。这是访问a.tcl中定义的变量的正确做法吗? b.tcl中$ condition的范围是什么?谢谢。
答案 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解释器的作用域总是在全局级别进行评估(即,在没有父作用域的::
名称空间中)。