在modulefile中加载模块时不能修改

时间:2014-05-21 13:42:02

标签: environment-variables tcl environment-modules modulefile

我想将模块加载到模块文件中(以解决依赖关系)。

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}中做更多的事情当然是功能。

任何人都知道发生了什么以及我缺少什么?

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也很有用 - 它将局部变量绑定到另一个范围内的变量 - 但不是你建议在这里使用的。我提到它是因为它可能对你有用做任何更复杂的事情......)