Why do I need an extra pair of brackets?

The following powershell script command

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

will print

  1: one
 2: two
 3: three

However, after removing the brackets around $l++

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

he will print

  : one
 : two
 : three
+6
source share
4 answers

This is because $l++ is a voidable expression. In powershell, certain types of expressions used as statements are not displayed. Voidable statements include assignments and increment / decment statements. When they are used in an expression, they return a value, but when theyre used as a standalone operator, they do not return a value. This is very well explained in Windows Powershell in action by Bruce Payette:

The increment and decrement operators were hardly included in PowerShell because they introduced the problem. In languages ​​like C and C #, when you use one of these operators as a statement: $ A ++ does not display anything. This is because the instructions in C and C # do not return a value. In However, PowerShell returns all values. This led to confusion. people will write scripts as follows:

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

and be surprised that the numbers 1 through 10 are displayed. This is because $ a ++ returns a value, and PowerShell displays the results of each statement. This was so confusing that we almost removed these statements from the language. Then we hit on the idea of ​​a statement of release. This basically means that certain types of expressions used as statements are not displayed. Invalid statements include assignments and increment / decment statements. When they are used in expressions, they return a value, but when theyre used as a standalone statement, they do not return a value. Again, this is one of those details that does not affect how you use PowerShell, except how to make it work as you expect. (source: Windows Powershell in action)

+12
source

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

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

Thus, the form of the $i++ operator does not display the value of $ i until it is incremented. If you want this behavior, PowerShell allows you to get this behavior by placing the increment (or decment) statement directly in the expression, for example:

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

This will exit @ (0,1).

Bruce Payette discusses this in Chapter 5 of Windows PowerShell in Action 2nd Edition . The increment and decrement operators are “exclusion statements”. Quote from the book:

This basically means that certain types of expressions, when used as statements, are not displayed. Invalid statements include assignment of operators and increment / decrement operators. Increments and decrements are used in the expression, they return a value, but when theyre used as a standalone operator, they do not return any value.

+4
source

This is because $l++ returns nothing:

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

This is to ensure that there is no confusion when you return to the conveyor. Effectively

$l++ $l = $l+ 1 , so it returns nothing.

What you want to see is $l = $l + 1; $l $l = $l + 1; $l , so you need to do ($l++) .

+1
source

I think that two tasks need to be completed:

  • Run $l++ (increment the variable), which occurs in the inner bracket
  • Get the value of $l that occurs in the outer bracket.

Here is an illustration of this:

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

Outputs: 1 where

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

It does not display anything.

To get the output, I need two operators inside the subexpression. Otherwise, it only happens that $l increases, but its value is not retrieved.

0
source

Source: https://habr.com/ru/post/906707/


All Articles