Maximilian Burszley
Maximilian Burszley

Reputation: 19664

PowerShell: The difference in parentheses expressions

I've been experimenting with the different forms of operators/expressions involving parentheses, but I can't find an explanation for an interaction I'm running into. Namely, ( ) and $( ) (subexpression operator) are not equivalents. Nor is it equivalent to @( ) (array operator). For most cases this doesn't matter, but when trying to evaluate the contents of the parentheses as an expression (for example, variable assignment), they're different. I'm looking for an answer on what parentheses are doing when they aren't explicitly one operator or another and the about_ documents don't call this out.


($var = Test-Something) # -> this passes through
$($var = Test-Something) # -> $null
@($var = Test-Something) # -> $null

about_Operators

Upvotes: 4

Views: 674

Answers (2)

js2010
js2010

Reputation: 27423

$( ) is unique. You can put multiple statements inside it:

$(echo hi; echo there) | measure | % count

2

You can also put things you can't normally pipe from, like foreach () and if, although the values won't come out until the whole thing is finished. This allows you to put multiple statements anywhere that just expects a value.

$(foreach ($i in 1..5) { $i } ) | measure | % count

5
$x = 10
if ( $( if ($x -lt 5) { $false } else { $x } ) -gt 20)
{$false} else {$true}
for ($i=0; $($y = $i*2; $i -lt 5); $i++) { $y }
$err = $( $output = ls foo ) 2>&1

Upvotes: 1

marsze
marsze

Reputation: 17055

For the array and subexpression operators, the parentheses are simply needed syntactically. Their only purpose is to wrap the expression the operator should be applied on.

Some examples:

# always return array, even if no child items found
@(Get-ChildItem -Filter "*.log").Count

# if's don't work inside regular parentheses
$(if ($true) { 1 } else { 0 })

When you put (only) parentheses around a variable assignment, this is called variable squeezing.

$v = 1 # sets v to 1 and returns nothing
($v = 1) # sets v to 1 and returns assigned value

You can get the pass-thru version for all your examples by combining variable squeezing with the subexpression operator syntax (that is, adding a second pair of parentheses):

($var = Test-Something)
$(($var = Test-Something))
@(($var = Test-Something))

Upvotes: 4

Related Questions