PoshCode Archive  Artifact Content

Artifact 627c3c9022fea50f5476cbb022797ff7a17dce19a1d6caff61a6203708eb6fda:

  • File Variable-capture.ps1 — part of check-in [c44c0c23f6] at 2018-06-10 13:44:44 on branch trunk — 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. (user: Public Domain size: 1257)

# 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
	}
}