函数如何调用它“覆盖”的函数?

函数如何调用它“覆盖”的函数?

例如,假设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 中,您不需要涉及 , 的复杂技巧whicheval也不需要考虑引用来重命名函数:只需使用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 $@[@] …
}

相关内容