Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding ruby splat in ranges and arrays

Tags:

ruby

splat

I'm trying to understand the difference between *(1..9) and [*1..9]

If I assign them to variables they work the same way

splat1 = *(1..9)  # splat1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
splat2 = [*1..9]  # splat2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

But things get weird when I try to use *(1..9) and [*1..9] directly.

*(1..9).map{|a| a.to_s}  # syntax error, unexpected '\n', expecting tCOLON2 or '[' or '.'
[*1..9].map{|a| a.to_s}  # ["1", "2", "3"...]

I'm guessing part of the problem is with operator precidence? But I'm not exactly sure what's going on. Why am I unable to use *(1..9) the same I can use [*1..9]?

like image 293
Dty Avatar asked Sep 26 '11 15:09

Dty


People also ask

What does * mean in Ruby in an array?

As stated by the other answers, the * operator is used to turn an array into an argument list. But what if the object is not an array, as in your case? Then Ruby will call #to_a on the object, if defined, and use the returned array instead. Otherwise, the object itself is used.

What does the splat operator do in Ruby?

A parameter with the splat operator converts the arguments to an array within a method. The arguments are passed in the same order in which they are specified when a method is called. A method can't have two parameters with splat operator.

How do you pass an array as an argument in Ruby?

It is also possible to pass an array as an argument to a method. For example, you might want a method that calculates the average of all the numbers in an array. Your main program might look like this: data = [3.5, 4.7, 8.6, 2.9] average = get_average(data) puts "The average is #{average}."

How do I merge two arrays in Ruby?

This can be done in a few ways in Ruby. The first is the plus operator. This will append one array to the end of another, creating a third array with the elements of both. Alternatively, use the concat method (the + operator and concat method are functionally equivalent).


1 Answers

I believe the problem is that splat can only be used as an lvalue, that is it has to be received by something.

So your example of *(1..9).map fails because there is no recipient to the splat, but the [*1..9].map works because the array that you are creating is the recipient of the splat.

UPDATE: Some more information on this thread (especially the last comment): Where is it legal to use ruby splat operator?

like image 62
bheeshmar Avatar answered Sep 28 '22 05:09

bheeshmar