PowerShell brain teaser

I’ve been following the buzz about the PowerShell Scripting Games on Twitter, and came across this PowerShell brain teaser from beefycode.

Here’s my answer, wish me luck!

In PowerShell, when is the following statement true? Explain why.

     ( $a -eq $b ) -ne ( $b -eq $a )


The key to this puzzle can be found in PowerShell help:

help about_Comparison_Operators -ShowWindow
Here’s the relevant paragraph from the help result:

When the input to an operator is a scalar value, comparison operators return a Boolean value. When the input is a collection of values, the comparison operators return any matching values. If there are no matches in a collection, comparison operators do not return anything. 

When we use the -eq operator in PowerShell, most assume it’s the same as the equals sign (=) in other programming languages, and using it would return a boolean result, and would return $true if the compared values match, and $false of they do not. And it would make sense that the order variables are specified shouldn’t matter, so if $a -eq $b then of course $b -eq $a
But the paragraph from the help topic above tells us that -eq and other comparison operators perform an additional function; if one of the compared values is a collection, like an array, it will return any matching values in the array, rather than a boolean result.
Let’s take an example. If $a is an integer, and $b is an array that contains that integer, the expression ( $a -eq $b ) is like asking “Hey PowerShell, is this integer variable $a equal to this array $b?”. However, if I switch the variables around, the expression ( $b -eq $a ) is like asking “Hey PowerShell, what values in this array $b are equal to this integer variable in $a?”
This PowerShell behavior is how we could get a $true result for the brain teaser expression:
 ( $a -eq $b ) -ne ( $b -eq $a ), like so:

 PS C:\Users\Dave> $a = 1

PS C:\Users\Dave> $b = 1,2

PS C:\Users\Dave> $a.GetType()

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Int32 System.ValueType

PS C:\Users\Dave> $b.GetType()

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array

PS C:\Users\Dave> $a -eq $b

PS C:\Users\Dave> $b -eq $a

PS C:\Users\Dave> ( $a -eq $b ) -ne ( $b -eq $a )

Any questions?

Leave a Reply

Your email address will not be published. Required fields are marked *