Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell 'x or y' assignment

There are several languages that provide either a defaulting or logical or mechanism for assignment:

a = b || c;
a = b or c
a="${b:-$c}"
a = b ? b : c;

So far the only equivalent I've found in Powershell Core is the exceedingly verbose:

$a = if ($b) { $b } else { $c }

which in some cases has to become

$a = if ($b -ne $null) { $b } else { $c }

Is there a better alternative [edit:] which doesn't sacrifice readability?

like image 473
kfsone Avatar asked Jul 24 '18 22:07

kfsone


People also ask

What does $_ mean 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 assign in PowerShell?

The equals sign ( = ) is the PowerShell assignment operator. PowerShell also has the following compound assignment operators: += , -= , *= , %= , ++ , -- , ??= . Compound assignment operators perform operations on the values before the assignment.

What does $() mean in PowerShell?

Subexpression operator $( ) For a single result, returns a scalar. For multiple results, returns an array. Use this when you want to use an expression within another expression. For example, to embed the results of command in a string expression. PowerShell Copy.

How do you assign a variable in PowerShell?

To create a new variable, use an assignment statement to assign a value to the variable. You don't have to declare the variable before using it. The default value of all variables is $null . To get a list of all the variables in your PowerShell session, type Get-Variable .


2 Answers

There's no || short-circuit operator in PowerShell assignments, and nothing equivalent to Perl's // "defined-or" operator - but you can construct a simple null coalesce imitation like so:

function ?? {
  param(
    [Parameter(Mandatory=$true,ValueFromRemainingArguments=$true,Position=0)]
    [psobject[]]$InputObject,

    [switch]$Truthy
  )

  foreach($object in $InputObject){
    if($Truthy -and $object){
      return $object
    }
    elseif($object -ne $null){
      return $object
    }
  }
}

Then use like:

$a = ?? $b $c

or, if you want to just have return anything that would have evaluated to $true like in your first example:

$a = ?? $b $c -Truthy
like image 57
Mathias R. Jessen Avatar answered Sep 28 '22 09:09

Mathias R. Jessen


So a simple method for reducing this:

$a = if ($b -ne $null) { $b } else { $c }

Would be to use the fact that true and false are just one or zero and could be used as an array index like so:

$a =  @($c, $b)[$b -ne $null]
like image 34
Dave Sexton Avatar answered Sep 28 '22 09:09

Dave Sexton