-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Type of issue
Other (describe below)
Feedback
The following example provided in the documentation is incorrect:
function Get-SumOfNumbers {
param (
[int[]]$Numbers
)
begin { $retValue = 0 }
process {
if ($null -ne $Numbers) {
foreach ($n in $Numbers) {
$retValue += $n
}
} else {
$retValue += $_
}
}
end { $retValue }
}
PS> 1, 2, 3, 4 | Get-SumOfNumbers
10
PS> Get-SumOfNumbers 1, 2, 3, 4
10
The condition if ($null -ne $Numbers)
always evaluates to $true
when numbers are provided, whether they are passed by parameter name or on the command line and results in executing the following foreach
block, potentially setting up an additional enumerator to enumerate over a single-element collection. I used the following function to evaluate this very same thing:
function Test-Pipeline {
Param(
[Parameter(ValueFromPipeline)]
[string[]] $Param
)
Begin {
if ($MyInvocation.ExpectingInput) {
Write-Host "BEGIN: One or more values for -Param were supplied via the pipeline! - $Input"
} else {
Write-Host "BEGIN: No values on the pipeline. `$Param: $Param"
}
Write-Host "BEGIN: `$Param: $Param"
}
Process {
Write-Host "PROCESS: Still expecting input in process? $($MyInvocation.ExpectingInput)"
Write-Host "PROCESS: `$Param is not null? $($null -ne $Param)"
Write-Host "PROCESS: The params are: $Param"
Write-Host "PROCESS: `$Input is: $Input"
Write-Host "PROCESS: `$_ is: $_"
}
End {
Write-Host "END: `$Param = $Param"
Write-Host "END: `$Input is: $Input"
}
}
Then I executed this function:
PS C:\> Test-Pipeline -Param 'foo', 'bar'
BEGIN: No values on the pipeline. $Param: foo bar
BEGIN: $Param: foo bar
PROCESS: Still expecting input in process? False
PROCESS: $Param is not null? True
PROCESS: The params are: foo bar
PROCESS: $Input is:
PROCESS: $_ is:
END: $Param = foo bar
END: $Input is:
PS C:\> 'foo', 'bar' | Test-Pipeline
BEGIN: One or more values for -Param were supplied via the pipeline! -
BEGIN: $Param:
PROCESS: Still expecting input in process? True
PROCESS: $Param is not null? True
PROCESS: The params are: foo
PROCESS: $Input is: foo
PROCESS: $_ is: foo
PROCESS: Still expecting input in process? True
PROCESS: $Param is not null? True
PROCESS: The params are: bar
PROCESS: $Input is: bar
PROCESS: $_ is: bar
END: $Param = bar
END: $Input is:
As you can see, whether or not the value for $Param
was passed by parameter or via the pipeline, inside the Process
block, $Param
always has a value. When passed via the pipeline, it only contains the current value coming in from the pipeline. Otherwise, it contains all of the values passed to the parameter.
So, the example in the documentation should be fixed as shown below. Also, it would be good for the documentation to mention that one can check for existing pipeline input by inspecting $MyInvocation.ExpectingInput
to achieve the desired result:
function Get-SumOfNumbers {
param (
[int[]]$Numbers
)
begin { $retValue = 0 }
process {
if ($MyInvocation.ExpectingInput) {
$retValue += $_
} else {
foreach ($n in $Numbers) {
$retValue += $n
}
}
}
end { $retValue }
}
PS> 1, 2, 3, 4 | Get-SumOfNumbers
10
PS> Get-SumOfNumbers 1, 2, 3, 4
10
Page URL
Content source URL
Author
Platform Id
b8594692-1518-3e24-d135-5382996ff646
Document Id
004bf422-04f5-50e2-3c89-2ff449d2867f