Powershell(基本的なこと003_再帰処理_クラス・ファンクション)

■Powershellの再帰処理の方法について考えてみる。
オセロのプログラムを組むにあたって、おそらく一番ネックになるのが再帰処理の方法だと思う。石を裏返す場合、状況によって2枚目まで見る場合、3枚目まで見る場合、4枚目まで見る場合、…といった形でここまで見ればいいというものがない(8×8の盤上なので最大はあるけど、つねに最大まで見るのは無駄が多そう)。バッチファイルを作ったときは、処理を指定の行までとばすgotoやフラグとなる変数を使ったりして何とか実現したけど、Powershellではどうだろう。今回は、再帰処理について検討してみる。

少し調べてみるとPowershellにはgotoに対応するようなものはなさそう。でも、クラス(Class)やファンクション(function)があったので、Javaとか他のプログラミング言語のようにできないものか。

まず、クラスの簡単なサンプルを試してみた。おそらくブランド名(Microsoft)が表示されるのだろうけど、動かしてみたらConstrainedLanguage modeではクラスは認められていないというエラーが出た(Class keyword is not allowed in ConstrainedLanguage mode.)。

class Device {
    [string]$Brand
}

$dev = [Device]::new()
$dev.Brand = "Microsoft"
$dev

モードを確認してみると確かにConstrained Languageとなっているけど、そういった設定をしたことはないので、デフォルトでこのモードになっているみたい。クラスが使えないので、一端ファンクションを試してみる。似たようなコードを動かしてみるとエラーもなく動いた。

function device ($a){
    $a
    return "hoge" + $a
}

$dev = device(111)
echo $dev

コードを書くにあたって、Javaなどのプログラムとは違うところもあった。
下のファンクションを動かすときに、定義した書き方と同じ記述にすると意図しない動きとなった。下のように2つの引数($b, $c)を定義して、動かすときに(555, 111)とした。それぞれ$bと$cに代入されると思っていたけど、どうやらカッコでくくった「555, 111」が1つの文字と判断され$bのみに代入されたよう。スペースを空けて555 111といった形にするのが正しいらしい。確かにコマンドプロンプトでは、引数はスペースを空けるけど、プログラミングのコードとしては、宣言した内容と同じように書くほうがなじみがある。

function device2 ($b, $c){
    $b
    return "hoge" + $c
}

device2 555 111
"================================"
device2 (555, 111)

次に、ファンクションで再帰処理ができないか試してみた。ファンクションの中で同じものを繰り返し呼ぶサンプルを作った。最終的に出てきた文字列は、予想したとおり繰り返し処理されていたので、オセロのプログラムの中でファンクションを使う方向で考えていく。

$i = 0

function device2 ($a){
    $a=$a+"bbb"+$i+"|  "
    "i:"+$i++ 
 if ($i -eq 100) {
    return "bbb"+$a
 } else {
    device2 ($a)
 }
}

$dev=device2 ccc
$dev