Env не изменяется при загрузке модуля в файл модуля
Я хотел бы загрузить модуль в файл модуля (для разрешения зависимостей).
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) }
или по крайней мере set tmp $env(PATH)
в MyModule после module load MyOtherModule
линия, среда правильно изменена. Это также работает нормально, если я не использую свою функцию addPath
но я использую prepend-path
команда, которая немного раздражает, потому что я хотел бы сделать больше вещей в addPath
Функция конечно.
Кто-нибудь как идея о том, что происходит и что мне не хватает?
1 ответ
prepend-path
вероятно, делает что-то "умное" для управления переменной; что именно, это то, чего я не знаю и не должен знать, потому что мы можем решить все это с помощью универсального Tcl. Чтобы ваша упаковка работала, используйте uplevel
для оценки кода в правильной области, хотя вы должны решить, использовать ли глобальную область (имя #0
) или объем звонящего (1
, который является значением по умолчанию); они одинаковы, когда ваша процедура addPath
вызывается с глобального уровня, но в остальном может быть совсем по- другому, и я не знаю, какие еще странности происходят с обработкой системы модулей.
Чтобы продемонстрировать, попробуйте это addPath
:
proc addPath {var val} {
puts stderr "BEFORE..."
uplevel 1 [list prepend-path $var $val]
puts stderr "AFTER..."
}
Мы используем list
создать объект для оценки в области действия вызывающего, так как гарантированно генерируются сценарии без единой команды без подстановок. (И действительные списки тоже.) В этом весь секрет генерации кода в Tcl: будьте проще, используйте list
чтобы сделать любое необходимое цитирование, вызовите вспомогательную процедуру (с подходящими аргументами), когда все усложняется, и используйте uplevel
контролировать объем оценки.
(NB: upvar
также может быть полезен - он связывает локальные переменные с переменными в другой области видимости - но это не то, что вам рекомендуется использовать здесь. Я упоминаю об этом, потому что это может быть полезно, если вы делаете что-то более сложное…)