たとえば、fpath
次のように設定されているとします。
( $HOME/.zsh/my-functions /usr/local/share/zsh/site-functions )
...そして関数定義ファイル$HOME/.zsh/my-functions/quux
とその両方が/usr/local/share/zsh/site-functions/quux
存在します。
quux
(これら2つのバージョンをそれぞれ「ユーザーの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 $@[@] …
}