web-dev-qa-db-ja.com

zsh: `source`コマンドは関数をリロードしません

(これはzsh 5.7.1を搭載したMacOSにあります)

以下は、zshでカスタム関数をロードする方法です。

# Custom functions
fpath=($HOME/.zfunc $fpath)
autoload -Uz mackupbackup
autoload -Uz tac
autoload -Uz airplane
autoload -Uz wakeMyDesktop

各関数は、~/.zfuncディレクトリにある独自のファイルです。このディレクトリは、mackupのおかげで別のディレクトリにシンボリックリンクされていることに注意してください。

現在のコミットハッシュをクリップボードにコピーする新しい関数を作成しました。 $ fpathにghashというファイルを作成し、関数を記述して、新しいautoload行を.zshrcに追加し、source ~/.zshrcを実行しました。

これが関数です

# copy the commit hash of the given git reference, or HEAD if none is given
ref=$1

if [[ $ref ]]; then
  git rev-parse $1 | pbcopy
else
  git rev-parse HEAD | pbcopy
fi

.zshrcをソースした後、関数が使用可能になり機能しましたが、機能したことの確認を印刷する行を追加したいと思いました。

echo "Copied $(pbpaste) to clipboard"

そのため、その行を追加してファイルを保存し、再度.zshrcを入手しました。

関数をもう一度実行しましたが、動作は変わりませんでした。

私は何か間違ったことをしたと思ったので、関数に変更を加え、.zshrcを無効にしてしまいました。全体として、私は.zshrcを22回再調達しました。その時点で、その操作が完了するまで37秒かかりました...

次に、関数をリロードしていない可能性があることに気付いたので、zshを実行して新しいインスタンスを開始し(約1秒かかりました)、関数は期待どおりに動作し始めました!

sourceが新しい関数を取得した理由は誰でも知っていますが、関数が変更されたときに更新されませんでしたか?

おまけの質問:実行するたびにsource ~/.zshrcの実行に時間がかかるのはなぜですか?

6
flyingsandwich

人々がべき等になるようにそれらを書くことはめったにないので、実際にうまくいくとしても、rcファイルを調達することはめったにありません。典型的な例はあなた自身のもので、毎回同じディレクトリをfpathパスの前に追加します。もちろん、そのパスを検索するたびに少し時間がかかります。さらに、あなたがそのようなことをしているのはここだけではありません。

また、オートローディングを正しく理解していません。 docoが述べるように、本体のない関数のオートロードは関数が最初に実行されるときに行われます。明らかに、関数がすでにロードされていて、本体がある場合、関数は再度ロードされません。

関数を再度unfunctioningする前に、関数をautoloadする必要があります。

Zシェルソースのサンプル_.zshrc_ には、引数として指定されたすべての関数に対してこれを実行するfreload()関数が含まれています。また、_typeset -U path cdpath fpath manpath_にも対応しています。

8
JdeBP

autoloadはzshの最初の参照でオートロードするためにnameをマークしますが、すでに定義されている場合、同じ名前の既存の関数は再定義しません。定義されました。希望どおりの結果を得るには、.zshrcを再度ソースする前に関数を未定義にするか、さらに効率化するために、オートロード用のラッパー関数を作成して、指定された関数名がすでに定義されているかどうかを確認します。オートロードするように再度マークする前に、それらの定義を解除してください。

.zshrcの調達が試行のたびに遅くなった理由については、.zshrcがなければ答えられません。

5
llua