Bash:Bash変数の露出を宣言された範囲に制限する方法はありますか?

Bash:Bash変数の露出を宣言された範囲に制限する方法はありますか?

次のスクリプトでは、関数(g)のローカル変数(i)の値が呼び出す関数(f)で上書きされます。

#!/usr/bin/env bash

f() {
    #local i # Let's assume whoever wrote this function f forgot,
             # to declare its variables as being local to it
    i=0
}

g() {
    local i # How to declare i as being only modifiable in the
            # scope of g, but not by functions g calls?
    for i in 1 2 3; do
        f # overwrites the value of i with 0
        echo "i: $i"
    done
}

g

# output:
# i: 0
# i: 0
# i: 0

bash変数の露出を宣言された範囲に制限する方法はありますか?

誰かが明示的にグローバル変数として宣言していない場合は、変数をローカル関数にデフォルト設定する方法はありますか(例:宣言-gを使用)。

答え1

唯一の方法は、サブシェルで問題のあるコードを実行することです。

g() {
    local i 
    for i in 1 2 3; do
        (f)           # <<
        echo "i: $i"
    done
}
i: 1
i: 2
i: 3

変数は、ローカル変数として宣言されない限り、グローバル変数です。これは避けられない。


localああ、この状況に直接影響を与える非常に重要な側面を忘れました。で宣言された「ローカル」変数はg読み書き可能です。g そして、次から呼び出されるすべての関数でg(任意の深さまで)。

  • iの変数はfのローカル範囲にありますg

~から手動(私のハイライト):

local関数内でのみ使用できます。その関数内でのみ変数名が表示されます。そしてその子供たち


非常に適切には、Perlのコマンドには同じ「問題」がありますが、local新しいコマンドで解決されましたmy

$ perl -e '
  sub f { $i = 10; }
  sub g { local $i = 5; f; print "$i\n"; }
  # ......^^^^^
  g
  '
10

$ perl -e '
  sub f { $i = 10; }
  sub g { my $i = 5; f; print "$i\n"; }
  # ......^^
  g
  '
5

関連情報