Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell - What does if($variable) test for?

Tags:

powershell

In Powershell, what does if($variable) test for? Is this testing if the variable is set, is null, is true, or something else?

like image 906
Bob Avatar asked Aug 08 '16 14:08

Bob


2 Answers

It tests whether the variable is true or whether a non-Boolean variable can be coalesced to true. For example, each of these return false:

$var #uninitialized
$var = ""
$var = $false
$var = 0

Each of these return true:

$var = "something"
$var = $true
$var = 1 #or any non-zero number
like image 177
morgb Avatar answered Oct 17 '22 14:10

morgb


Powershell uses loose typing, and as a part of this any value can be used as a conditional expression. The logic of evaluating values to true or false (such values are often called "truthy" and "falsey") is in the System.Management.Automation.LanguagePrimitives.IsTrue function. The logic is the following:

  • $null evaluates to false.
  • $true and $false have their usual meaning.
  • A numeric value (int, double, decimal etc.) is truthy, if it is non-zero.
  • A string is truthy, if it is non-empty.
  • A switch parameter evaluates to true, if it has been supplied by the caller.
function Test 
{
   param ( [switch]$Option )
}

Test # $Option evaluates to false
Test -Option # $Option evaluates to true

# (Technically, $Option is not bool; it is of type SwitchParameter which, 
# for almost all intents and purposes, can be used interchangeably with bool.)
  • A collection (implementing IList) uses the following logic: An empty collection is falsey; a collection with only one element evaluates to the truth value of its member; a collection with two or more elements is truthy.
  • Anything else is truthy.

There are a couple of gotchas:

  • The char type is not a numeric type. Indeed, [System.Management.Automation.LanguagePrimitives]::IsTrue([char]0) returns True (per the final clause); yet if([char]0) { "Truthy" } else { "Falsey" } returns "Falsey". I wasn't able to find the reason why this happens.
  • As mentioned above, a collection with exactly one element is evaluated by evaluating its member. So what happens if you try to evaluate a collection which only contains itself (or a recursive or very deeply nested chain of collections, each with one element)? For science, you can test it:
$array = New-Object -TypeName System.Object[] 1 # $array = new object[1]
$array[0] = $array
if($array) { "Truthy" } else { "Falsey" }

(The answer is: it crashes the process with StackOverflowException.)

like image 35
Mike Rosoft Avatar answered Oct 17 '22 14:10

Mike Rosoft