読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

スクリプトブロックと変数のスコープ

以下のコマンドの結果をみて、「ローカル変数はスクリプトブロック内でもアクセス可能なんだな」と認識していたのですが、

PS C:\> function call( $proc ) { &$proc }
PS C:\> $a = 100
PS C:\> call { echo $a }
100

$aに値を代入すると、期待と異なる結果に。

PS C:\> function call( $proc ) { &$proc }
PS C:\> $a = 100
PS C:\> call { echo $a; $a = 10; echo $a }
100
10
PS C:\> echo $a
100

ブロック内で代入したのに、外の値が更新されていない!ブロック内の出力を見る限りでは$aの参照と代入は正しくできているようなのだけど。ということで調べてみたら、CodeZine - Windows PowerShell 入門(8)−関数編3がヒット。こちらは関数内でのスコープの話なのだけど恐らく↑もおなじで、スクリプトブロックの外の$a」と「スクリプトブロック内の$a」が別の変数となっているのが原因みたいです。まとめると、

  • スクリプトブロックの外側で宣言した変数が、スクリプトブロックに封入される訳ではない。
    • ↑の例でブロック内で$aが参照できるのは、$aが「ローカル変数」になっていて、配下のスコープからも参照できるから。
    • $aをprivateにすると、ブロック内からは参照できなくなる。
PS C:\> $private:a = 100
PS C:\> call { echo $private:a; $private:a = 10; echo $private:a }
10
PS C:\> echo $private:a
100
  • 参照はできるけど、ブロック内で「$a=10」とかすると、新たに変数が作成される。★ここがはまりポイント。
  • で、ブロックの中で外の$aを更新したい場合は、$aのスコープが「スクリプト」であることを明示すればよい。
PS C:\> $a = 100
PS C:\> call { echo $script:a; $script:a = 10; echo $script:a }
100
10
PS C:\> echo $a
10

なかなか、趣深いな > Power Shell。