LoginSignup
0
0

More than 5 years have passed since last update.

PowerShell・再帰・トランポリン

Last updated at Posted at 2018-09-06

ネタ元

JavaScript・再帰・トランポリン

PowerShellで似たようなことをやってみたくなったので、やってみた。

バージョン

PowerShellでスタックオーバーフローを起こしたいなら黙ってv2を使うんだ。

PS C:\> $PSVersionTable.PSVersion.ToString()
2.0

スタックオーバフローが起きる関数

filter countDown ($num)
{
  if ($num -eq 1) {return 1}
  if ($num % 200 -eq 0) {Write-Host $num}
  countDown ($num - 1)
}
PS C:\> countDown 1000
1000
800
600
400
200
呼び出しの深さのオーバーフローのため、スクリプトが失敗しました。呼び出しの深さが 1001 に達しましたが、最大値は 1000 です。
    + CategoryInfo          : InvalidOperation: (1001:Int32) []、ParentContainsErrorRecordException
    + FullyQualifiedErrorId : CallDepthOverflow

評価が遅延されるように、関数を定義し直す。

filter countDown2 ($num)
{
  if ($num -eq 1) {return 1}
  if ($num % 200 -eq 0) {Write-Host $num}
  New-Trampoline $function:countDown2 ($num - 1)
}

filter New-Trampoline
  ([ScriptBlock] $ScriptBlock, [Object[]]$ArgumentList)
    {$ScriptBlock | Add-Member NoteProperty ArgumentList $ArgumentList -PassThru}

トランポリン

filter Invoke-Trampoline
{
  while ($_ -is [ScriptBlock] -and ($_ | Get-Member ArgumentList))
    {$_ = Invoke-Command $_ -ArgumentList $_.ArgumentList}

  $_
}

確かにスタックオーバーフローは起こらなくなる

PS C:\> countDown2 1000 | Invoke-Trampoline
1000
800
600
400
200
1

おもしろ~い

おわり

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0