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