# encoding: ascii
# api: powershell
# title: gather/take
# description: Port of Perl 6’s gather/take (which itself is a port of Mathematica’s Reap/Sow)
# version: 1.1
# type: function
# author: Public Domain
# license: CC0
# x-poshcode-id: 5131
# x-archived: 2014-05-05T01:59:30
# x-published: 2014-04-30T20:42:00
#
#
function gather {
#.SYNOPSIS
# Port of Perl 6's gather/take (which itself is a port of Mathematica's Reap/Sow)
#.PARAMETER Using
# An already existing ArrayList to append to
#.EXAMPLE
# gather { 1 ; take 2 ; 3 ; take 4 5 }
# 2
# 4
# 5
#.NOTES
# PowerShell doesn't really need this since the pipeline does this by default
# (and does a much better job since it works by using a push streaming model)
# but it's useful in the rare cases that it's necessary.
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[scriptblock]$Script
,
[ValidateNotNull()]
[System.Collections.IList]$Using
)
try {
${function:take} = (New-Object System.Management.Automation.PSModuleInfo $true).NewBoundScriptBlock({
foreach ($null in $args) { $null = $script:acc.Add([string]$foreach.Current) }
})
& ${function:take}.Module { $script:acc = $args[0] } $(if ($PSBoundParameters.ContainsKey('Using')) { ,$Using } else { ,[System.Collections.ArrayList]@() })
} catch {
throw
}
$null = & $Script
if (-not $PSBoundParameters.ContainsKey('Using')) {
& ${function:take}.Module { $script:acc }
}
}