Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is it legal to use ruby splat operator?

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?

like image 892
Dave Nolan Avatar asked Apr 22 '09 09:04

Dave Nolan


People also ask

What is splat operator in Ruby?

Splat operator or start (*) arguments in Ruby define they way they are received to a variable. Single splat operator can be used to receive arguments as an array to a variable or destructure an array into arguments. Double splat operator can be used to destructure a hash.


1 Answers

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 as foo = (*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 than foo = bar || zap? Even in a case like a, 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 by a, 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:

def foo(a, b, c)
  #important stuff happens here!
end

foo(*bar = [1, 2, 3]) will splat after the assignment and set the arguments to 1, 2, and 3 respectively. Compare that with foo((*bar = [1, 2, 3])) which will complain about having the wrong number of arguments (1 for 3).

like image 135
Pesto Avatar answered Oct 06 '22 00:10

Pesto