Hugh asks:

> irb(main):001:0> x = [[[2.3],4,[5,6]]]
> [[[2.3], 4, [5, 6]]]
> irb(main):002:0> *x
> SyntaxError: compile error
> irb(main):003:0> p *x
> [[2.3], 4, [5, 6]]
> nil

> Not sure why *x didn't work there...  

Well, there's no such construct as plain *x. But there are constructs for
indexing (aref_args), multiple left hand side on assignment (mhls), multiple
right hand side on assignment (mrls), call arguments (call_args), when
arguments (when_args) and function definition parameter list (f_arglist)
where the star symbol (tSTAR) have special meaning. (The names in
parentheses could be found from parse.y, if you want to check.)

So in above case *x does not parse, thus there's an error, but p *x parses,
as it means p(*x) and call_args rule parses *x. Namely *x in this context
takes an array of x and translates the elements to be arguments. That means
it concatenates the elements to the argument list, thus "removes" the
outmost level of array.

Thus the difference of p x and p *x is not very visible, but very
significant:

p  x  [[[2.3], 4, [5, 6]]]
p *x   [[2.3], 4, [5, 6]]

By investigating the other constructs I listed, you'll find out the
different uses for *constructs.

	- Aleksi