Bug #16010

Sole single-splatted variable with an array object in an assignment construction gobbles an additional nesting of array

Added by sawa (Tsuyoshi Sawada) 10 months ago. Updated 10 months ago.

Target version:


When a single splatted variable appears as the sole argument on the left side of assignment with an array on the right side, that variable is assigned the object as is on the right side:

*foo = ["a"]; foo # => ["a"]

This behavior looks inconsistent to me, and I am suspecting it is a bug from the reasons below.

First, all other constructions that involve assignment of objects to variables work in the same way to one another, but in a different way from the above. That is, they add another nesting level of an array:

instance_exec(["a"]){|*foo| foo} # => [["a"]]

->*foo{foo}.call(["a"]) # => [["a"]]

def baz(*foo); foo end; baz(["a"]) # => [["a"]]

Second, if the object on the right side of the assignment construction in question is not an array, then another level of nesting is added:

*foo = "a"; foo # => ["a"]

The splat on a variable can be understood to collect the objects into an array. However, in the first example above in which the right side object is an array, all of a sudden, the additional nesting level of array becomes absent. It is not obvious why it behaves differently when the object to be collected is already an array.

Third, when there is no remaining object for the splatted variable, the variable is assigned an empty array,

*foo, bar = "baz"; foo # => []

and when more than one objects remain for the splatted variable, the variable is assigned an array that includes those objects, even if they are arrays:

*foo, bar = ["a"], ["b"], "c"; foo # => [["a"], ["b"]]

But when there is exactly one object that corresponds to the splatted variable, that object is not included in an array, but is given as is.

In short, I believe the correct behavior should be as follows:

*foo = ["a"]; foo # => [["a"]]

Also available in: Atom PDF