Comparison operator and function references

Viewed 36

Referencing a function as the left-hand side of the -eq operator produces results that I can't explain:

PS C:\> function mj { 23 }
PS C:\> mj -eq 23
23
PS C:\> mj -eq 45
23

The first case almost makes it seem as though the function's return value is being interpreted as a collection of size one (maybe to accommodate functions with multiple statements), but that theory doesn't hold for the second case.

Referencing the function from within a grouping operator or as a sub-expression yields more intuitive results:

PS C:\> (mj) -eq 23
True
PS C:\> (mj) -eq 45
False
PS C:\> $(mj) -eq 23
True
PS C:\> $(mj) -eq 45
False

Given these more predictable forms, the practical response to the first examples may be "don't do that." Still, I'd like to understand what's going on since I'm concerned about where/how the underlying behavior could impact other code.

PS C:\> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      19041  1320
1 Answers

I believe the comments have been explanatory, the grouping operator (..) is necessary not only for precedence but also, as demonstrated in the example from the Doc, it allows you to let output from a command participate in an expression.

Without it, PowerShell interprets -eq as a parameter of the function mj and 23 as an argument for said parameter.

You can test this by adding $args or a parameter that takes ValueFromRemainingArguments to your function:

function mj { 23; $args }

function mjWithRemainingArgs {
    param(
        [parameter(ValueFromRemainingArguments)]
        $remargs
    )

    23; $remargs
}

PS /> mj -eq 23
23
-eq
23

PS /> mjWithRemainingArgs -eq 45
23
-eq
45
Related