Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell Arrays and Parenthesis

Coming from other programming languages, I would expect the following statements to all produce the same result. Can someone explain why the parenthesis make a difference here?

PS D:\>   "ab",      "cd"
ab
cd
PS D:\>  "a"+"b" ,  "c"+"d"
ab cd
PS D:\>  "a"+"b" , ("c"+"d")
ab cd
PS D:\> ("a"+"b"),  "c"+"d"
ab
c
d
PS D:\> ("a"+"b"), ("c"+"d")
ab
cd
PS D:\>
like image 420
sparebytes Avatar asked Apr 24 '14 21:04

sparebytes


1 Answers

The applicable rules are as follows:

  • The , is a unary or binary operator that creates an array of the operand(s), and it has higher precedence than the + operator.
  • The + operator can be used for numerical addition, string concatenation, and array concatenation. The data type of the left operand determines which type of operation is performed. If possible, the right operand is cast as the data type of the left operand; if not possible, an error is thrown. *
  • Where precedence is equal, evaluation occurs left to right.
  • Arrays are cast as strings by listing the elements separated by spaces.
  • Parentheses, as you'd expect, have higher precedence than any operator, and cause the enclosed expression to be evaluated before anything outside the parentheses.
  • The default output of an array object is a list of elements, one on each line.

* That explains seemingly inconsistent results such as that "foo" + 1 evaluates to foo1, but 1 + "foo" gives you an error.

So, let's take a look at your test cases, and analyze what happens following the logic explained above.


Case I:

"ab", "cd"

This one is very straightforward: the , operator creates an array of two strings, ab and bc.


Case II:

"a" + "b", "c" + "d"

This one seems counter-intuitive at a first glance; the key is to realize that , is evaluated before +. Here's how the result is obtained, step by step:

  1. "b", "c" is evaluated first (due to ,'s precedence over +), creating an array of the elements b and c.
  2. Next, the + operator is applied to "a" and the array created in step 1. Since the left operand "a" is a string, a string concatenation is performed.
  3. To concatenate a string with an array, the array is cast as a string. An array of b and c becomes the string b c.
  4. Concatenating a with b c yields ab c.
  5. Finally, ab c is concatenated with d to produce the final result, ab cd

Case III:

"a"+"b" , ("c"+"d")

This yields the same result by coincidence; the evaluation occurs differently:

  1. ("c"+"d") is evaluated first, due to the parentheses. That's a plain vanilla string concatenation, which results in the string cd.
  2. Next, the , operator is applied to "b" and the string from step 1, creating an array of the elements b and cd. (This is evaluated before "a" + "b" because , has higher precedence than +.)
  3. Then, the + operator is applied to "a" and the array created in step 2. Since the left operand is a string, a string concatenation is performed.
  4. The array of b and cd is cast as the string b cd.
  5. The strings a and b cd are concatenated, resulting in the final output ab cd.

Case IV:

("a" + "b"),  "c" + "d"

This is the most interesting test case, and probably the most counter-intuitive, because it yields results that may appear inconsistent. Here's how it's evaluated:

  1. Similar to Case III step 1, ("a" + "b") is evaluated first, producing the string ab.
  2. The , is applied to the string from step 1 and "c", creating an array of the elements ab and c.
  3. The + operator is applied to the array from step 2 and the next token, "d". This time, the left operand is an array, so an array concatenation is performed.
  4. The string operand "d" is cast as an array of one element.
  5. The two arrays are concatenated into an array of the elements ab, c, and d.

Case V:

("a" + "b"), ("c" + "d")

By now, it should be easy to see what happens here:

  1. ("a" + "b") is evaluated as the string ab.
  2. ("c" + "d") is evaluated as the string cd.
  3. The , is applied to the strings from steps 1 and 2, creating an array of ab and cd.

You can see the precedence table with the command

Get-Help about_Operator_Precedence

(Help doc names can be tab-completed, so to save typing, that's help about_opTABTAB)

like image 78
Adi Inbar Avatar answered Sep 22 '22 16:09

Adi Inbar