Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the syntax [*a..b] mean in Ruby?

NOTE: mischa's splat on GitHub has lots of cool interactive examples of * in action.

By googling, I found that one way to iterate over a range of numbers in Ruby (your classic C-style for loop)

for (i = first; i <= last; i++) {
  whatever(i);
}

is to do something like this

[*first..last].each do |i|
  whatever i
end

But what exactly is going on with that [*first..last] syntax? I played around with irb and I see this:

ruby-1.9.2-p180 :001 > 0..5
 => 0..5 
ruby-1.9.2-p180 :002 > [0..5]
 => [0..5] 
ruby-1.9.2-p180 :003 > [*0..5]
 => [0, 1, 2, 3, 4, 5] 
ruby-1.9.2-p180 :004 > *0..5
SyntaxError: (irb):4: syntax error, unexpected tDOT2, expecting tCOLON2 or '[' or '.'
*0..5
    ^

Everything I've read online discusses the unary asterisk as being useful for expanding and collapsing arguments passed to a method, useful for variable length argument lists

def foo(*bar)
  bar 
end

foo 'tater' # => ["tater"]
foo 'tater', 'tot' # => ["tater", "tot"]

and I get that, but I don't see how it applies to the expansion being done in my block example above.

To be clear, I know that The Ruby Way is to iterate over an array or collection, not to use the array length and iterate with an integer index. However, in this example, I really am dealing with a list of integers. :)

like image 907
Justin Force Avatar asked May 12 '11 17:05

Justin Force


People also ask

What does ||= mean in Ruby?

In ruby 'a ||= b' is called "or - equal" operator. It is a short way of saying if a has a boolean value of true(if it is neither false or nil) it has the value of a. If not it has the value of b.

What does {} do in Ruby?

Ruby blocks are anonymous functions that are enclosed in a do-end statement or curly braces {} . Usually, they are enclosed in a do-end statement if the block spans through multiple lines and {} if it's a single line block.

What is an identifier in Ruby?

Identifiers are names of variables, constants, and methods. Ruby identifiers are case sensitive. It means Ram and RAM are two different identifiers in Ruby. Ruby identifier names may consist of alphanumeric characters and the underscore character ( _ ).


1 Answers

[*1..10]

is the same thing as

(1..10).to_a # call the "to array" method

Instances of the Array class you have created implement Enumerable so your loop works. On classes that define a to_a method, you can use the splat operator syntax with brackets. Splat does a lot more than just call #to_a though, and would be worth a Google search on its own.

Now, in your case, the Range class itself is already an Enumerable so you could just do:

(first..last).each do |v| 
  ...
end
like image 59
DigitalRoss Avatar answered Sep 25 '22 12:09

DigitalRoss