そもそもPowershellのスコープとは
スコープとは、変数の有効範囲である。
スコープの種類は次の通り。
- global
- スクリプトファイル内・外であっても、どこからでも読み書きできる。
- script
- 同一スクリプトファイルに限り、どこからでも読み書きできる。
- local
- 現在スコープからの読み書き、子スコープからは読み取りのみできる。
- 同一スコープ、子スコープから読み書き可能と書いているサイトが多かったが、挙動的には子スコープからは読み取りしかできないように見えた。もしかすると間違っているかも。
- private
- 現在のスコープ内からのみ読み書きできる。
失敗例
下記の場合、関数と主処理でスコープが異なるので、値を更新できない。
(参照はできる)
sample_fault.ps1
# 変数に文字列を追加する関数
function Add-Str(){
# 変数に"bar"を追加
$STR += "bar"
}
# 変数に"foo"を設定
$STR = "foo"
# 関数を呼び出し
Add-Str
# 変数STRは更新されていない
# "foo"が表示される
Write-host $STR
実行結果
foo
対処1(変数にスコープを定義する)
変数のスコープをgrobalもしくはscriptに定義してあげれば、子スコープからも値を更新できる。
わざわざスコープを変数に書かないといけないのがめんどくさい。
sample_success1.ps1
# 変数に文字列を追加する関数
function Add-Str(){
# 変数に"bar"を追加
$script:STR += "bar"
}
# 変数に"foo"を設定
$script:STR = "foo"
# 関数を呼び出し
Add-Str
# 変数STRは更新され、"foobar"が表示される
Write-host $script:STR
実行結果
foobar
対処2(ドットソース形式で処理を呼び出す)
ドットソースで処理を呼び出すと、呼出元と呼出先の変数のスコープが同一となる。
下記の場合は、関数Add-Strを呼び出すときに「. 」を追加すればOK。
sample_success2.ps1
# 変数に文字列を追加する関数
function Add-Str(){
# 変数に"bar"を追加
$STR += "bar"
}
# 変数に"foo"を設定
$STR = "foo"
# 関数を呼び出し
. Add-Str
# 変数STRは更新され、"foobar"が表示される
Write-host $STR
実行結果
foobar
参考サイト
http://mtgpowershell.blogspot.jp/2010/11/blog-post_28.html
http://dev.knowlbo.co.jp/entry/2016/12/08/132431