例如,假设fpath
设置为
( $HOME/.zsh/my-functions /usr/local/share/zsh/site-functions )
...并且函数定义文件$HOME/.zsh/my-functions/quux
和都/usr/local/share/zsh/site-functions/quux
存在。
(我将分别将这两个版本称为quux
“用户的quux
”和“站点的quux
”。)
此外,假设我已经跑了
autoload -U quux
这意味着,如果我现在运行quux
,将运行的是用户的quux
.
本文标题中的“覆盖”一词是指在这种情况下,用户的quux
“覆盖”网站的quux
. (我可以用“阴影”代替“覆盖”。)
我的问题是:有没有办法让用户quux
依次调用网站的quux
? (在典型情况下,用户quux
将处理传递给站点的参数quux
,和/或处理其产生的输出。)
我正在寻找不需要修改任何内容的解决方案/usr/local/share/zsh/site-functions/quux
。
重要的:fpath
这个问题中使用的是只是一个例子。一般来说,我们所知道的是,一个函数可以通过fpath
覆盖(影子)其他一些此类函数来访问。
我尝试过卑鄙的计划,例如,$HOME/.zsh/my-functions/quux
采用一般形式
# one-time initialization
local body
body=$( SOMEHOW <???> GET SOURCE CODE OF OVERRIDDEN FUNCTION )
eval "overridden_quux () {
$body
}"
# self-re-definition (MWAH-HA-HA-HA-HAAAA!)
quux () {
local massaged_args
massaged_args=( $( MASSAGE ARGS "$@" ) )
__overridden_quux "$massaged_args" | MASSAGE OUTPUT
}
# one-time re-invocation
quux "$@"
...但结果非常脆弱,更不用说方法的丑陋了。
答案1
最简单的方法是强制加载原始函数,重命名它,然后在您的 中重新定义它.zshrc
,而不是在您的 fpath 中使用同名的函数。请注意,在 zsh 中,您不需要涉及 , 的复杂技巧which
,eval
也不需要考虑引用来重命名函数:只需使用functions
关联数组。
autoload -Uz +X quux
functions[overridden_quux]=$functions[quux]
quux () {
… overridden_quux $@[@] …
}
如果您希望从 fpath 中的文件自动加载该函数,那么它会变得很繁琐,因为您需要加载原始文件而不递归访问相同的 fpath 条目。我没有比本地重新定义更好的解决方案fpath
。
#autoload quux
functions[overridden_quux]=$(
fpath=("${(@)fpath:#$HOME/*}")
autoload -Uz +x quux
print -r -- $functions[quux]
)
quux () {
… overridden_quux $@[@] …
}