Reputation: 29159
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
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
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
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
Reputation: 52587
I think there are two tasks it needs to do:
$l++
(increment the variable) which happens on the inner parenthesis$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