zshの関数定義における変数の拡張

zshの関数定義における変数の拡張

zshで関数を定義すると、変数の評価/拡張に問題があります。これは可能ですか?例:

variable=foo
mytest(){
  echo ${variable}  
}
mytest           //outputs foo
variable=bar
test           //outputs bar

test() の変数が foo のままで、もはや $variable の影響を受けないことを願っています。ドキュメントを読んで評価やさまざまな参照を試しましたが、何も機能しないようです。

答え1

一度設定された値を保持する変数は関数の内部になければなりません。これはグローバル変数でのみ実行できるため、次のように別の名前を指定する必要があります。

xtest(){
  typeset -g test_variable
  : ${test_variable:=$variable}
  echo $test_variable
}

これはtest_variable関数が最初に呼び出されたときに設定されますが、それ以降は上書きされません。

更新:Stéphane Chazelasによって提供された説明に基づいて関数定義の構文を変更し、関数名をtestからxtestに変更しました。とにかく関数名を「test」と指定するのは悪い考えだからです。

答え2

zshまず、Bourne シェルの関数定義構文は次のとおりです。

funcname() cmd

(ksh構文と他のいくつかの構文もサポートしていますがfunction funcname {...}

funzsh構文キーワードではありません。の場合と機能を本文としてfun foo() cmd定義できます。funfoocmd

また、標準コマンド(組み込みおよびほとんどのBourne様シェル)名をtest関数名として使用しないことをお勧めします。testzsh

ひとりが欲しいなら地元の固定値を持つ変数の場合は、その値を関数定義に含める必要があります。

mytest() {
  local variable=test
  echo $variable
}

variableこの関数はローカルですが、mytestこの関数によって呼び出された他の関数(存在する場合)にはまだ表示されます。他の関数から非表示にするには(つまり、静的にスコープする)代わりに(モジュールprivate内)を使用できます。zsh/param/privatelocal

欲しいなら固定値$variable定義時には、グローバル変数の値としてmytest次のように定義に含める必要があります。

zmodload zsh/param/private
eval '
  mytest() {
    private variable='${(qq)variable}'
    echo $variable
    otherfunction ...
  }
'

${(qq)...}変数の内容を定義に含めます(正しい引用符を含む)。

関連情報