シェルスクリプトの処理境界が鮮明になる「名前付きブロック記法」なるものを考えてみたという記事を先日読みました。
主張としては、1ファイル内での処理境界を分けるために使うとのこと。それにしても関数で十分事足りるよな、というのが自分の感想でしたが、.zshrc
で自分が抱えていたちょっとした問題を解決してくれるきっかけになりました。
関数が邪魔な時もある
自分の.zshrc
の抜粋です。設定が百行単位になった頃から大まかな処理を関数で分けるようになりました。先の記事でいうところの、処理境界を明確にするためです。
my-zsh::command_line_editting() {
# Emacs風のキーバインド
bindkey -e
# Alt+F, Alt+B でアルファベット、マルチバイト文字以外の文字を区切り文字とする
autoload -Uz select-word-style
select-word-style default
zstyle ':zle:*' word-chars " /:@+|"
zstyle ':zle:*' word-style unspecified
}
(中略)
my-zsh::command_line_editting
しかし、この関数、ログインシェルの起動後も残ります。
% functions my-zsh::command_line_editting
my-zsh::command_line_editting() {
# Emacs風のキーバインド
bindkey -e
# Alt+F, Alt+B でアルファベット、マルチバイト文字以外の文字を区切り文字とする
autoload -Uz select-word-style
select-word-style default
zstyle ':zle:*' word-chars " /:@+|"
zstyle ':zle:*' word-style unspecified
}
シェル起動時に使うだけで再利用のあてもないのに、これはちょっと邪魔っけです。また他の関数と名前が被ってトラブルになることを恐れて、関数名にmy-zsh::
とプレフィックスをつけるようになりました。なぜ一度きりの関数にこう、気を使わないとダメなんだ……
無名関数で名前付きブロックをつくる
時期を同じくして、zshには無名関数があることを知りました。
そこで名前付きブロックの考え方と組み合わせて、.zshrc
の記述を以下のようにしてみました。
: "Commandline Editing" && () {
# Emacs風のキーバインド
bindkey -e
# Alt+F, Alt+B でアルファベット、マルチバイト文字以外の文字を区切り文字とする
autoload -Uz select-word-style
select-word-style default
zstyle ':zle:*' word-chars " /:@+|"
zstyle ':zle:*' word-style unspecified
}
&&
の先のブロックを関数にしておいて、変数にdeclare
、local
、typeset
など使えるところが自分の好みです。気にならないなら、元記事のように{ グループコマンド }
を使う方が記述がきれいですね。
無名関数は処理を記述した場所で即時実行され、その定義は残りません。これで関数邪魔っけ問題を解決できました。
些細な悩みだったのですが、解決できてうれしいです。