2

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
Mike
  • 123
  • 1
  • 5
  • 2
    when you do `mj -eq 23` without the grouping operator `(...)` powershell thinks you're trying to pass the argument `23` to the parameter `-eq` of the function `mj` – Santiago Squarzon Feb 24 '22 at 18:48
  • To see this in action, try `function mj($eq) { $eq + 1 }` instead. Fun! If you *really* want to mess with people's minds, make the function return a boolean instead. – Jeroen Mostert Feb 24 '22 at 18:49
  • 2
    The `-eq` tokens in your first examples is _not_ the operator - PowerShell interprets `eq` as a parameter name. `Get-Help about_Parsing` – Mathias R. Jessen Feb 24 '22 at 18:49
  • Good question; the linked duplicate has some additional info. – mklement0 Feb 24 '22 at 20:49

1 Answers1

1

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
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37