Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return one and only one value from a PowerShell function?

Tags:

powershell

I've learned from this Stack Overflow question, that PowerShell return semantics are different, let's say, from C#'s return semantics. Quote from the aforementioned question:

PowerShell has really wacky return semantics - at least when viewed from a more traditional programming perspective. There are two main ideas to wrap your head around: All output is captured, and returned. The return keyword really just indicates a logical exit point.

Let's look at this example:

function Calculate {    echo "Calculate"    return 11 }  $result = Calculate 

If you echo $result you will realise that something is not right. You'd expect this:

11 

But the reality, what you actually see, is different:

Calculate 11 

So instead of getting back only the intended return value, you actually get back an array.

You could get rid of the echo statements and not polluting the return value, but if you call another function from your function, which echoes something, then you're in trouble again.

How can I write a PowerShell function that only returns one thing? If the built-in PowerShell functions do return only one value, why can't I do that?

The workaround that I'm using now and I'd love to get rid of:

function Calculate {    # Every function that returns has to echo something    echo ""    return 11 }  # The return values is the last value from the returning array $result = (Calculate)[-1] 
like image 857
Balázs Szántó Avatar asked Apr 10 '15 08:04

Balázs Szántó


People also ask

How do you return a value from a function in PowerShell?

If you are inside of a function and return a value with the return keyword, the function will return that value and exit the function. The return keyword causes the function to exit after outputting the first process. PowerShell will then generate output for both processes.

Can a function only return one value?

Even though a function can return only one value but that value can be of pointer type.

What does $_ do in PowerShell?

The $_ is a variable or also referred to as an operator in PowerShell that is used to retrieve only specific values from the field. It is piped with various cmdlets and used in the “Where” , “Where-Object“, and “ForEach-Object” clauses of the PowerShell.

How do I return multiple variables from a function in PowerShell?

Since PowerShell does not apply any restriction on data type returned, it created a lot of possibilities on what can be returned as an output of the function. So if one needs to return multiple values or objects, it is generally suggested to create an array of the objects and then return the array.


2 Answers

You can also just assign everything to null, and then return just the variable you want:

Function TestReturn {      $Null = @(         Write-Output "Hi there!"         1 + 1         $host         $ReturnVar = 5     )     return $ReturnVar } 
like image 167
Nate Avatar answered Sep 18 '22 21:09

Nate


Several answers already given do not fully answer your question because they do not account for other cmdlets you might call--as you point out--that might "pollute" your output. The answer from @Laezylion is essentially correct but I believe bears further elaboration.

It is clear that you appreciate that your current workaround--forcing every function to return an array then taking the last element--is not a very robust solution. (In fact, I think it is safe to call that a kludge. :-) The correct approach--and a direct answer to your question--is clear... though at first glance it sounds like a tautology:

Question: How do you ensure a function returns only one thing? Answer: By ensuring that it returns only one thing. 

Let me elucidate. There are really two kinds of functions/cmdlets in PowerShell: (A) those that return data and (B) those that do not return data but may instead report progress or diagnostic messages. Problems arise, as you have seen, when you try to mix the two. And this may easily happen inadvertently. Thus, it is your responsibility, as the function author, to understand each function/cmdlet call within your function: specifically, does it return anything, be it a true return value or just diagnostic output? You are expecting output from type A functions, but you need to be wary of any type B functions. For any one that does return something you must either assign it to a variable, feed it into a pipeline, or... make it go away. (There are several ways to make it go away: pipe it to Out-Null, cast it to void, redirect it to $null, or assign it to $null. See Jason Archer’s Stack Overflow post that evaluates the performance of each of these flavors, suggesting you shy away from Out-Null.)

Yes, this approach takes more effort, but you get a more robust solution by doing so. For a bit more discussion on this very issue, these A/B functions, etc. see Question 1 on A Plethora of PowerShell Pitfalls recently published on Simple-Talk.com.

like image 28
Michael Sorens Avatar answered Sep 21 '22 21:09

Michael Sorens