はじめに
Powershellスクリプトを書いていて、下記のようなゼロ埋めのロジックを実装したんだけど、
テスト中に挙動がおかしいと言われたので調査してみました。
#$numが[0-9]の場合2桁目に"0"を挿入したい
function ZeroPadding ([int]$num) {
if([int]($num/10) -eq 0){
[String]$strNum = "0" + [String]$num
return $strNum
}else{
return [String]$num
}
}
想定される実行結果は、こうなるはず。
$num = ZeroPadding -num 0
-> 00
$num = ZeroPadding -num 1
-> 01
$num = ZeroPadding -num 2
-> 02
$num = ZeroPadding -num 3
-> 03
$num = ZeroPadding -num 4
-> 04
$num = ZeroPadding -num 5
-> 05
$num = ZeroPadding -num 6
-> 06
$num = ZeroPadding -num 7
-> 07
$num = ZeroPadding -num 8
-> 08
$num = ZeroPadding -num 9
-> 09
$num = ZeroPadding -num 10
-> 10
実際の結果は以下の通り。
$num = ZeroPadding -num 0
-> 00
$num = ZeroPadding -num 1
-> 01
$num = ZeroPadding -num 2
-> 02
$num = ZeroPadding -num 3
-> 03
$num = ZeroPadding -num 4
-> 04
$num = ZeroPadding -num 5
-> 05
$num = ZeroPadding -num 6
-> 6
$num = ZeroPadding -num 7
-> 7
$num = ZeroPadding -num 8
-> 8
$num = ZeroPadding -num 9
-> 9
$num = ZeroPadding -num 10
-> 10
What the Hell !?!?
$numに[6-9]入れたときの挙動がおかしい??
思わず「は?」って100回くらい言いました。
なにが起こったか
どうやら、[Double] -> [Int32]へキャストする際の挙動がおかしいみたいだ。
[int](1/10)
-> 0
[int](2/10)
-> 0
[int](3/10)
-> 0
[int](4/10)
-> 0
[int](5/10)
-> 0
[int](6/10)
-> 1
[int](7/10)
-> 1
[int](8/10)
-> 1
[int](9/10)
-> 1
[int](10/10)
-> 1
どうやらPowershellで[Double] -> [Int32]へのキャストは 5捨6入 になるらしい。
なぜなんだ Powershell。
シェルスクリプトとはいえ、テストの重要性を思い知らされた一瞬でした。
どうするか
調べたところ、PadLeftメソッドが利用できそうです。
(PadRightもあるみたいです。)
#$numが[0-9]の場合2桁目に"0"を挿入したい
function ZeroPadding ([String]$num) {
#$str.PadLeft("桁数","埋める文字列")
return $num.PadLeft(2,"0")
}
関数すら必要ないくらいスマートになりました。
とりあえず10回回してみましょう。
for($i=0;$i-le10;$i++){
$num = ZeroPadding -num $i
Write-Host("num = ${num}")
}
num = 00
num = 01
num = 02
num = 03
num = 04
num = 05
num = 06
num = 07
num = 08
num = 09
num = 10
うまくできました。
無駄な実装をしてしまう前にまずはググりましょう。という教訓を得ました。