読んだ後24.2。ローカル変数var
、キーワードを使用して変数を宣言することは、関数の中かっこで区切られたコードブロック内でのみその値にアクセスできることlocal
を意味すると思いました。var
var
しかし、次の例を実行した後、このコードブロックで呼び出された関数からアクセス、読み書きすることができることがわかりました。つまり、 とvar
宣言された場合でも依然として読み取り変更することができます。値。local
outerFunc
innerFunc
#!/usr/bin/env bash
function innerFunc() {
var='new value'
echo "innerFunc: [var:${var}]"
}
function outerFunc() {
local var='initial value'
echo "outerFunc: before innerFunc: [var:${var}]"
innerFunc
echo "outerFunc: after innerFunc: [var:${var}]"
}
echo "global: before outerFunc: [var:${var}]"
outerFunc
echo "global: after outerFunc: [var:${var}]"
出力:
global: before outerFunc: [var:] # as expected, `var` is not accessible outside of `outerFunc`
outerFunc: before innerFunc: [var:initial value]
innerFunc: [var:new value] # `innerFunc` has access to `var` ??
outerFunc: after innerFunc: [var:new value] # the modification of `var` by `innerFunc` is visible to `outerFunc` ??
global: after outerFunc: [var:]
Q:これは私のシェル(bash 4.3.42、Ubuntu 16.04、64ビット)のバグですか、それとも予想される動作ですか?
編集する:解決しました。 @MarkPlotnickが指摘したように、これは実際に予想される動作です。
ベストアンサー1
シェル変数にダイナミックレンジ。変数が関数に対してローカルに宣言されている場合、その範囲は関数が返されるまで有効です。他の関数の呼び出し中に含める!
これはほとんどのプログラミング言語とは明らかに対照的です。語彙範囲。 Perl には次の両方があります。my
語彙範囲の場合、local
または動的範囲のない宣言です。
2つの例外があります。
ksh93 で標準構文を使用して関数を定義すると、
function_name () { … }
そのローカル変数は動的スコープに従います。ただし、関数がksh構文を使用して定義されている場合、function function_name { … }
そのローカル変数は語彙/静的範囲に従うため、呼び出された他の関数には表示されません。zsh/private
自動ロードプラグインは、静的範囲で変数を宣言するために使用できるキーワード/組み込み関数を提供zsh
しますprivate
。
ash、bash、pdksh、およびその派生物であるboshにはダイナミックレンジしかありません。