Splats are cool. They're not just for exploding arrays, although that is fun. They can also cast to Array and flatten arrays (See http://github.com/mischa/splat/tree/master for an exhaustive list of what they do.)
It looks like one cannot perform additional operations on the splat, but in 1.8.6/1.9 the following code throws "unexpected tSTAR":
foo = bar || *zap #=> unexpected tSTAR
Whereas this works:
foo = *zap || bar #=> works, but of limited value
Where can the splat appear in an expression?
First, precedence isn't an issue here, because
foo = bar || (*zap)
works no better. The general rule of thumb is that you cannot perform additional operations on a splat. Even something as simple asfoo = (*zap)
is invalid. This applies to 1.9 as well.Having said that, what do you expect
foo = bar || *zap
to do, if it worked, that is different thanfoo = bar || zap
? Even in a case likea, b = bar || *zap
(which also doesn't work),a, b = bar || zap
accomplishes what I'd assume would be the same thing.The only situation where this might make any sense is something like
a, b = foo, bar || *zap
. You should find that most cases where you would want to use this are covered bya, b = foo, *(bar || zap)
. If that doesn't cover your case, you should probably ask yourself what you really hope to accomplish by writing such an ugly construct.EDIT:
In response to your comments,
*zap || bar
is equivalent to*(zap || bar)
. This demonstrates how low the splat's precedence is. Exactly how low is it? The best answer I can give you is "pretty low".For an interesting example, though, consider a method
foo
which takes three arguments:foo(*bar = [1, 2, 3])
will splat after the assignment and set the arguments to 1, 2, and 3 respectively. Compare that withfoo((*bar = [1, 2, 3]))
which will complain about having the wrong number of arguments (1 for 3).The "splat operator" is in fact not an operator at all but a token defined in the Ruby grammar. A read through grammar.y or the Ruby grammar in BNF form* will tell you that it is allowed as the last or only argument:
&foo
)&foo
)a, b, *cs = [1,2,3,4]
a, b, c = 1, 2, *[3,4,5]