# encoding: ascii
# api: powershell
# title: Variable capture
# description: Powershell really needs lexical variables and automatic lexical closures. ScriptBlock.GetNewClosure is a heavyweight hack (it captures the entire scope chain every time you call it) around lexical variable capture so here is a lighter weight hack.
# version: 0.1
# type: function
# author: Public Domain
# license: CC0
# function: New-Closure
# x-poshcode-id: 4694
# x-archived: 2013-12-16T12:32:22
# x-published: 2013-12-13T00:59:00
#
#
function New-Closure {
#.SYNOPSIS
# A more fine grained approach to capturing variables than GetNewClosure
#.EXAMPLE
# $acc = New-Closure @{t = 0} {param($v = 1) $t += $v; $t} ; & $acc 10 ; & $acc
# 10
# 11
[OutputType([scriptblock])]
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[System.Collections.IDictionary]$Variable
,
[Parameter(Mandatory)]
[scriptblock]$Script
)
try {
$private:m = New-Object System.Management.Automation.PSModuleInfo $true
$Script = $m.NewBoundScriptBlock($Script)
foreach ($v in $Variable.GetEnumerator()) {
& $m { Set-Variable -Name $args[0] -Value $args[1] -Scope script -Option AllScope } $v.Key $v.Value
}
$Script
} catch {
throw
}
}