함수는 자신이 "재정의"하는 함수를 어떻게 호출합니까?

함수는 자신이 "재정의"하는 함수를 어떻게 호출합니까?

예를 들어 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 $@[@] …
}

관련 정보