我想将模块加载到模块文件中(以解决依赖关系)。
MyModule的:
#%Module########################################
##
## Modulefile
#
proc ModulesHelp { } {
puts stderr "Env for MyProg"
}
proc addPath {var val} {
prepend-path $var $val
}
module load MyOtherModule
addPath PATH /opt/MyModule/bin
MyOtherModule:
#%Module########################################
##
## Modulefile
#
proc ModulesHelp { } {
puts stderr "Env for MyOtherProg"
}
proc addPath {var val} {
prepend-path $var $val
}
addPath PATH /opt/MyOtherModule/bin
当我运行module load MyModule
时,两个模块似乎都被加载但环境不对:
$module list
Currently Loaded Modulefiles:
1) MyModule 2) MyOtherModule
$echo $PATH
/opt/MyModule/bin:/usr/bin:/bin
如果我在foreach p [array names env] { set tmp $env($p) }
行之后的MyModule中添加了行set tmp $env(PATH)
或至少module load MyOtherModule
,则会正确修改环境。如果我不使用我的函数addPath
它也可以正常工作,但我直接使用prepend-path
命令,这有点烦人,因为我想在{{1}中做更多的事情当然是功能。
任何人都知道发生了什么以及我缺少什么?
答案 0 :(得分:3)
prepend-path
可能正在做一些“聪明”的事情来管理一个变量;究竟是什么我不知道也不需要知道,因为我们可以使用通用Tcl解决所有问题。要使其包装正常工作,请使用uplevel
来评估适当范围内的代码,但需要考虑是使用全局范围(名称#0
)还是调用者范围({{1 ,这是默认值);从全局级别调用过程1
时它们是相同的,但是否则完全不同,我不知道模块系统正在发生什么其他奇怪的事情处理
要演示,请尝试以下addPath
:
addPath
我们使用proc addPath {var val} {
puts stderr "BEFORE..."
uplevel 1 [list prepend-path $var $val]
puts stderr "AFTER..."
}
来构造要在调用者范围内进行评估的事物,因为它可以保证生成无替换的单命令脚本。 (也是有效的列表。)这是在Tcl中进行代码生成的全部秘诀:保持简单,使用list
进行任何所需的引用,在事情变得复杂时调用辅助程序(带有合适的参数),以及使用list
来控制评估范围。
(注意:uplevel
也很有用 - 它将局部变量绑定到另一个范围内的变量 - 但不是你建议在这里使用的。我提到它是因为它可能对你有用做任何更复杂的事情......)