none
Behaviour "-contains" Operator RRS feed

  • Question

  • Help guys

    Plaese say me, why when i run statement "1 -or 2 -contains 3" i receive True. How me uderstand this?



    Thursday, September 11, 2014 11:42 AM

Answers

  • Simple logic 101:

    PS C:\scripts> 1 -or 2 -contains 3
    True
    PS C:\scripts> (1 -or 2) -contains 3
    True
    PS C:\scripts> (1 -or 2)
    True
    PS C:\scripts> $true -contains 3
    True
    PS C:\scripts> $true -contains $true
    True
    PS C:\scripts>

    This is due to coercion.   The left most arguments set the type.  If the type is Boolean then the '3'  is evaluated as a boolean.

    PS C:\scripts> [bool]3
    True
    PS C:\scripts> [bool]0
    False

    Only '0' is ever false.

    -contains is a logical test and always returns a Boolean.  This forces the result to be Boolean and the leftmost is Boolean:

    1 -or 2

    any -OR anyother

    these will always be $true

    PS C:\scripts> 'true' -or 'false'
    True
    PS C:\scripts> $true -or $false
    True

    $true -contains $true

    SO........

    PS C:\scripts> $true -contains 999999999
    True
    PS C:\scripts> $true -contains 0
    False


    ¯\_(ツ)_/¯


    • Proposed as answer by Sam Boutros Thursday, September 11, 2014 12:06 PM
    • Edited by jrv Thursday, September 11, 2014 12:07 PM
    • Marked as answer by Sergey Aslanov Thursday, September 11, 2014 1:13 PM
    Thursday, September 11, 2014 12:03 PM

All replies

  • You're supposed to use this syntax:

    1,2 -contains 3

    The expression:

    1 -or 2

    evaluates to True

    The expression:

    $True -contains "anything" 

    Will always evaluate to True,

    The expression:

    $False -contains "anything"
    will always evaluate to False


    Sam Boutros, Senior Consultant, Software Logic, KOP, PA http://superwidgets.wordpress.com (Please take a moment to Vote as Helpful and/or Mark as Answer, where applicable) _________________________________________________________________________________ Powershell: Learn it before it's an emergency http://technet.microsoft.com/en-us/scriptcenter/powershell.aspx http://technet.microsoft.com/en-us/scriptcenter/dd793612.aspx


    • Edited by Sam Boutros Thursday, September 11, 2014 12:04 PM
    Thursday, September 11, 2014 11:56 AM
  • Simple logic 101:

    PS C:\scripts> 1 -or 2 -contains 3
    True
    PS C:\scripts> (1 -or 2) -contains 3
    True
    PS C:\scripts> (1 -or 2)
    True
    PS C:\scripts> $true -contains 3
    True
    PS C:\scripts> $true -contains $true
    True
    PS C:\scripts>

    This is due to coercion.   The left most arguments set the type.  If the type is Boolean then the '3'  is evaluated as a boolean.

    PS C:\scripts> [bool]3
    True
    PS C:\scripts> [bool]0
    False

    Only '0' is ever false.

    -contains is a logical test and always returns a Boolean.  This forces the result to be Boolean and the leftmost is Boolean:

    1 -or 2

    any -OR anyother

    these will always be $true

    PS C:\scripts> 'true' -or 'false'
    True
    PS C:\scripts> $true -or $false
    True

    $true -contains $true

    SO........

    PS C:\scripts> $true -contains 999999999
    True
    PS C:\scripts> $true -contains 0
    False


    ¯\_(ツ)_/¯


    • Proposed as answer by Sam Boutros Thursday, September 11, 2014 12:06 PM
    • Edited by jrv Thursday, September 11, 2014 12:07 PM
    • Marked as answer by Sergey Aslanov Thursday, September 11, 2014 1:13 PM
    Thursday, September 11, 2014 12:03 PM
  • As Sam posted the other side which is that the type of the left most part determines how the test is made.

    1,2,4,5 -contains 3

    is:

    PS C:\scripts> $x=@(1,2,4,5)
    PS C:\scripts> $x.Gettype()

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

    PS C:\scripts> $x.Contains(3)
    False

    Now the same demonstration fails for Boolean so PowerShell is assuming something about Booleans on the left that the Boolean type does not know about.  It would appear to bean error in some circumstances so we would want to be careful that we are using a collection and not an expression that returns something unexpected.  The left expression cannot be allowed to evaluate to a Boolean.



    ¯\_(ツ)_/¯

    Thursday, September 11, 2014 12:16 PM
  • Simple logic 101:

    PS C:\scripts> 1 -or 2 -contains 3
    True
    PS C:\scripts> (1 -or 2) -contains 3
    True
    PS C:\scripts> (1 -or 2)
    True
    PS C:\scripts> $true -contains 3
    True
    PS C:\scripts> $true -contains $true
    True
    PS C:\scripts>

    This is due to coercion.   The left most arguments set the type.  If the type is Boolean then the '3'  is evaluated as a boolean.

    PS C:\scripts> [bool]3
    True
    PS C:\scripts> [bool]0
    False

    Only '0' is ever false.

    -contains is a logical test and always returns a Boolean.  This forces the result to be Boolean and the leftmost is Boolean:

    1 -or 2

    any -OR anyother

    these will always be $true

    PS C:\scripts> 'true' -or 'false'
    True
    PS C:\scripts> $true -or $false
    True

    $true -contains $true

    SO........

    PS C:\scripts> $true -contains 999999999
    True
    PS C:\scripts> $true -contains 0
    False


    ¯\_(ツ)_/¯


    According to this:

    http://technet.microsoft.com/en-us/library/hh847842.aspx

    -contains has a higher precedence than -or, so I'd think the evaluation would look more like:

    1 -or (2 -contains 3)
    Which is still going to evaluate to $true because 1 will always coerce to $true.


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    • Proposed as answer by jrv Thursday, September 11, 2014 1:26 PM
    Thursday, September 11, 2014 12:39 PM
    Moderator
  • You are correct.  It is precedence and not coercion. Due to that the parens would be on "contains". Good catch.

    ¯\_(ツ)_/¯

    Thursday, September 11, 2014 1:26 PM