tags:

views:

4113

answers:

3

I am seeing some rather weird behavior with PowerShell, it looks like custom functions might need a "parenthesis wrapper" to evaluate as you might expect them. Given a simple PowerShell function:

function Return-True { return $true }

and then some sample code to invoke it:

PS C:\> Return-True
True
PS C:\> Return-True -eq $false
True
PS C:\> (Return-True) -eq $false
False

Ideas? Comments?

+2  A: 

The second line is not doing a boolean evaluation. Look at what happens if you do the same thing with strings.

PS C:\> function Return-True { return "True string" }
PS C:\> Return-True
True string
PS C:\> Return-True -eq "False string"
True string
PS C:\> (Return-True) -eq "False string"
False

The second line is simply returning the value of the function, and not doing a comparison. I'm not sure exactly why this behavior is happening, but it makes the behavior easier to see than when using boolean values that are being converted to the strings "True" and "False".

hurcane
+12  A: 

When PowerShell sees the token Return-True it identifies it as a command and until evaluation or end of the statement, everything else is an argument which is passed to the function Return-True.

You can see this in action if you do:

PS > function Return-True { "The arguments are: $args"; return $true }
PS > Return-True -eq $false
The arguments are: -eq False
True

That's why all of the following return 'True', because all you are seeing is the result of calling Return-True with various arguments:

PS > Return-True -eq $false
True
PS > Return-True -ne $false
True
PS > Return-True -eq $true
True
PS > Return-True -ne $true
True

Using (Return-True) forces PowerShell to evaluate the function (with no arguments).

Grant Wagner
+2  A: 

If you use PowerShell V2's editor, you would see that -eq in the first example is blue, because it is an argument and -eq in the second example is gray because it is an operator

Also in V2, you can be strict about arguments, with CmdletBinding and param

function Return-True
{
    [CmdletBinding()]
    param()
    return $true
}
Return-True -eq $false

Return-True -eq $false
Return-True : A parameter cannot be found that matches parameter name 'eq'.
At line:7 char:16
+ Return-True -eq <<<<  $false
    + CategoryInfo          : InvalidArgument: (:) [Return-True], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Return-True
mrwaim