The following code, although I would think should return a single value, returns an array.
function Do-Something {
123
return 456
}
(Do-Something).GetType() # will say Object[]
I learned that if I want to avoid this I have to pipe the unwanted values to Out-Null like so
function Do-Something {
123 | Out-Null
return 456
}
However, I couldn't find any reasoning behind why PowerShell is implemented this way. I find that this can lead to nasty and silent bugs if you forget that something has a return value that you did not capture. Could someone explain when this could come in handy? Also is it possible to force powershell not to collect all uncaptured variables in an array?
To create and initialize an array, assign multiple values to a variable. The values stored in the array are delimited with a comma and separated from the variable name by the assignment operator ( = ). The comma can also be used to initialize a single item array by placing the comma before the single item.
In PowerShell, you can assign values to multiple variables using a single command. The first element of the assignment value is assigned to the first variable, the second element is assigned to the second variable, the third element to the third variable. This is known as multiple assignment.
The “$_” is said to be the pipeline variable in PowerShell. The “$_” variable is an alias to PowerShell's automatic variable named “$PSItem“. It has multiple use cases such as filtering an item or referring to any specific object.
array . Clear() Sets all item values to the default value of the array's item type.
PowerShell emits the output of all statements in a script or function into the output pipe because it's a shell and that's how shells work. The return
statement is somewhat regrettable in that functions don't return objects, they write objects into the pipeline. Being able to terminate the execution of a function is necessary but we probably should have called it something else. The ability to simply emit objects makes simple scripts simpler because there is no need for explicit output statements or returns. Does it sometimes cause problems - yes, sometimes it does. Consequently, for classes, as introduced in V5, we went with more traditional programming language semantics. If a method in a class is going to return something, it must declare a return type and it must use the return
statement to return a value, otherwise nothing will be returned.
Anything written to the output stream is considered part of the pipeline - return
is a bit of a misnomer in Powershell. While it does "return" a value, anything else previously written to the output stream is also part of the "returned value". In Powershell, use return
to "write to the pipeline and exit the current function". It's more like what break
is to a loop than what a traditional return
directive is to a function or method.
If you want to output 123
but not as part of the pipeline, consider using Write-Verbose
, Write-Warning
, Write-Debug
, or Write-Host
(this would be an appropriate use of Write-Host
since you do not want the output to be considered as part of the pipeline).
As for why it works this way, it works like this in most other shell languages, and should be expected. Any STDOUT
output in a cmd
, sh
, or bash
for example can be stored in a variable, piped to another command, or otherwise redirected. While Powershell is a powerful scripting language, it is still also an interactive shell, and behaves as such.
Though you are not alone in thinking that return
is confusing considering its implied meaning based on most other programming languages.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With