ca9163d9
ca9163d9

Reputation: 29159

Why it needs an extra pair of bracket?

The following powershell script

"one","two","three" | % { "$(($l++)): $_" }

will print

1: one
2: two
3: three

However, after remove the bracket around $l++

"one","two","three" | % { "$($l++): $_" }

it will print

: one
: two
: three

Upvotes: 6

Views: 335

Answers (4)

Keith Hill
Keith Hill

Reputation: 201652

I believe this was a design decision made by the PowerShell team to avoid surprises due to PowerShell outputting return values. Many C/C# folks would expect the following function to only output 1 not @(0,1).

function foo {
  $i = 0
  $i++
  $i
}

So the statement form $i++ doesn't output the value of $i before it is incremented. If you want that behavior, PowerShell allows you to get that behavior by putting the increment (or decrement) statement directly inside an expression e.g.:

function foo {
  $i = 0
  ($i++)
  $i
}

This will output @(0,1).

Bruce Payette discusses this in Chapter 5 of Windows PowerShell in Action 2nd Edition. The increment and decrement operators are "voidable statements". Quoting from the book:

Basically, this means that certain types of expressions, when used as statements, are not displayed. Voidable statements include assignment statements and the increment/decrement operators. When increment and decrement are used in an expression, they return a value, but when they’re used as a standalone statement, they return no value.

Upvotes: 4

jon Z
jon Z

Reputation: 16616

This is because $l++ is a voidable statement. In powershell certain types of expressions, when used as statements, are not displayed. Voidable statements include assignments and the increment/decrement operators. When they are used in an expression, they return a value, but when they’re used as a standalone statement, they return no value. It is very well explained in Windows Powershell in Action by Bruce Payette:

The increment and decrement operators were almost not included in PowerShell because they introduced a problem. In languages such as C and C#, when you use one of these operators as a statement: $a++ nothing is displayed. This is because statements in C and C# don’t return values. In PowerShell, however, all statements return a value. This led to confusion. People would write scripts like this:

$sum=0
$i=0
while ($i -lt 10) { $sum += $i; $i++ }
$sum

and be surprised to see the numbers 1 through 10 displayed. This was because $a++ returned a value and PowerShell was displaying the results of every statement. This was so confusing that we almost removed these operators from the language. Then we hit on the idea of a voidable statement. Basically, this means that certain types of expressions, when used as statements, are not displayed. Voidable statements include assignments and the increment/decrement operators. When they are used in an expression, they return a value, but when they’re used as a standalone statement, they return no value. Again, this is one of those details that won’t affect how you use PowerShell other than to make it work as you expect. (source: Windows Powershell in Action)

Upvotes: 12

manojlds
manojlds

Reputation: 301147

That is because $l++ doesn't return anything, :

$l = 0
$l++   #nothing
$l #gives 1
$l++   #nothing
($l++)  #gives 2

This is done so that there is no confusion when you are returning to pipeline. Effectively,

$l++ is $l = $l+ 1, so it doesn't return anything.

What you want to see is $l = $l + 1; $l, which is why you have to do ($l++).

Upvotes: 1

Andy Arismendi
Andy Arismendi

Reputation: 52587

I think there are two tasks it needs to do:

  1. Execute $l++ (increment the variable) which happens on the inner parenthesis
  2. Retrieve $l's value which happens in the outer parenthesis.

Here is a illustration of this:

$l = 0
"$($l++ ; $l)"

Outputs: 1 where

$l = 0
"$($l++)"

Doesn't output anything.

In order to receive output I need two statements inside the sub-expression. Otherwise the only thing that happens is that $l is incremented but its value is not retrieved.

Upvotes: 0

Related Questions