Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does 'true' equal $true

Tags:

powershell

I'm not quite sure if this exact question is a duplicate, but I couldn't find my specific question on stackoverflow, so I guess it's not.

$true is a boolean type:

($true).getType()

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

'true' is a string:

('true').gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

why is this condition true?

PS C:\WINDOWS\system32> if ('True' -eq $true) {'yes'} else {'no'}
yes

only because the string is called True just like the boolean true? If I compare it with any other string, there is a different outcome:

PS C:\WINDOWS\system32> 'hello' -eq $true
False
PS C:\WINDOWS\system32> 'true' -eq $true
True

if you do 'true' == true in C# it prints an cannot convert string to bool error and both C# and PS are based on .net and have quite the same syntax. why is there a different outcome? this seems very strange to me.

How is PowerShell evaluating 'true' to $true?

like image 563
SimonS Avatar asked Mar 12 '23 06:03

SimonS


1 Answers

In PowerShell, operator overloading is determined by the left-hand side (lhs) argument.

This means that when you supply a string as the lhs argument, the parser will attempt to convert the right-hand side (rhs) to a string as well.

When cast to a string, $true comes out as the string "True" - which, since PowerShell's string comparison operators are all case-insensitive by default, happens to equal "true".

This operation:

'true' -eq $true

Is interpreted as

'true' -eq 'True'

Which happens to be $true, satisfying your if condition.


With $true, this also happens to work the other way around, because a non-empty string, when converted to a boolean, evaluates to $true:

In other words

$true -eq 'true'

Is interpreted as

$true -eq $true

This can lead to confusion, since the string "false" will incidentally also be evaluated as $true, simply because the string "false" is not empty:

PS C:\> $true -eq "true"
True
PS C:\> $true -eq "false"
True
PS C:\> $true -eq ""
False
like image 179
Mathias R. Jessen Avatar answered Mar 30 '23 12:03

Mathias R. Jessen