rubyの配列の演算 [*arr1 + arr2] の仕組みが分からない

[code]

    arr1 = ["1","2"]
    arr2 = ["3","4"]
    
    [*arr1 + arr2] #=> ["1","2","3","4"]
    
[/code]

となります.

`Array#+` のソースも覗いてみましたがなぜこうなるのかわかりませんでした.

どのようなプロセスでこのような結果が返ってくるのか, よろしければ教えていただけませんか.




`Array#+` によって配列が連結されます

[code]

    arr1 + arr2 #=>["1", "2", "3", "4"]
    
[/code]

また、ここでの`*`は配列を以下のように展開します

[code]

    arr = [1,2]
    a, b = *arr #a => 1 b => 2
    a, b = 1, 2 #これと同じ
    
[/code]

`*arr1 + arr2`は`*(arr1 + arr2)`と同義で`"1", "2", "3", "4"` と展開されます。したがって

[code]

    [*arr1 + arr2]
    [*(arr1 + arr2)]
    [*(["1", "2", "3", "4"])]
    ["1", "2", "3", "4"]
    
[/code]

となります




該当コードの動作解釈については @suzukisさん、@yasuさん、@BLUEPIXY さんの解答通りかと思います。

この回答は `*` よりも先に `+` が評価される理由、つまり `[(*arr1) + arr2]` ではなく `[*(arr1 + arr2)]`
と評価される仕組みを、興味本位で[Ruby言語仕様(Draft)](http://www.ipa.go.jp/osc/english/ruby/ruby_draft_specification_agreement.html)から調べた結果となります。

Rubyの（厳密な意味での）単項演算子としては、`-`, `~`, `+`, `!`の4種類しか存在しません。  
つまり単項演算子`*`というものは存在しないので、`[(*arr1) + arr2]`と解釈されることはありえません。ここでの `*` は、文法上は
splatting-argument の一部として解釈されます。

プライマリ式(primary-expression) `[ * arr1 + arr2 ]`
を、Ruby処理系が構文解析していく過程は次の通りです（終端記号への置き換えを伴わない中間過程は全部省略しています）：

  * **`[ * arr1 + arr2 ]`** → **array-constructor** → **`[`** indexing-argument-list **`]`**
  * `[` **`* arr1 + arr2`** `]` → `[` **splatting-argument** `]` → `[` **`*`** operator-expression `]`
  * `[` `*` **`arr1 + arr2`** `]` → `[` `*` **additive-expression** `]` → `[` `*` additive-expression **`+`** multiplicative-expression `]`
  * `[` `*` **`arr1`** `+` **`arr2`** `]` → `[` `*` **variable** `+` **variable** `]`

* * *

文法定義より部分的に引用

> primary-expression ::  
>  array-constructor  
>  | variable-reference  
>  | ...
>
> array-constructor ::  
>  `[` indexing-argument-list _?_ `]`
>
> indexing-argument-list ::  
>  splatting-argument  
>  | ...
>
> splatting-argument ::  
>  `*` operator-expression
>
> operator-expression ::  
>  conditional-operator-expression  
>  | ...
>
> ～
>
> unary-operator-expression ::  
>  unary-minus-expression  
>  | unary-expression
>
> unary-minus-expression ::  
>  power-expression  
>  | `-` power-expression
>
> power-expression ::  
>  unary-expression  
>  | ...
>
> unary-expression ::  
>  primary-expression  
>  | `~` unary-expression  
>  | `+` unary-expression  
>  | `!` unary-expression
>
> variable-reference ::  
>  variable  
>  | ...
>
> variable ::  
>  constant-identifier  
>  | global-variable-identifier  
>  | class-variable-identifier  
>  | instance-variable-identifier  
>  | local-variable-identifier

