Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does powershell collect uncaptured values and returns it as an array

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?

like image 838
Peter Avatar asked Jul 10 '18 12:07

Peter


People also ask

How does PowerShell store data 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.

How do I store multiple values in a variable in PowerShell?

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.

What is $_ in PowerShell?

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.

How do you clear an array in PowerShell?

array . Clear() Sets all item values to the default value of the array's item type.


2 Answers

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.

like image 194
Bruce Payette Avatar answered Sep 29 '22 01:09

Bruce Payette


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.

like image 34
Bender the Greatest Avatar answered Sep 29 '22 03:09

Bender the Greatest