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. :)
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.
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.
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..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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With