1

I am new to Ruby. I found this code while reading a tutorial

10.times { |i | print i, " " } # o/p => 0 1 2 3 4 5 6 7 8 9  

I know times repeat a action number of times it's called. I assume that i gets initialised to 0. But, how it's getting incremented?

Balaji Radhakrishnan
  • 1,010
  • 2
  • 14
  • 28
  • 1
    The `times` method does the incrementing. `times` is a method for the integer object, in this case, `10`, and it accepts a block as an argument (the `{...}` part) that it executes inside a loop. – lurker Feb 10 '15 at 10:48
  • Thanks for the response. But, I need another clarification. if times is an integer object and it gets increments every time how 3.times{puts "Hi!"}. prints Hi! Hi! Hi? – Balaji Radhakrishnan Feb 10 '15 at 10:50
  • 1
    Why don't you check in `times` method source: http://www.ruby-doc.org/core-2.2.0/Integer.html#method-i-times – Marek Lipka Feb 10 '15 at 10:51
  • 1
    `times` is not an integer object. It is a *method` for the integer object. In Ruby, numbers are objects, meaning they are a class with methods. `times` is one of those methods. – lurker Feb 10 '15 at 10:52

3 Answers3

2

times creates an array of incrementing numbers (well an Enumerator actually, but it can be converted to an array with to_a)

$ irb
irb(main):001:0> 3.times.to_a
=> [0, 1, 2]
irb(main):002:0> 10.times.to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

See: http://www.ruby-doc.org/core-2.2.0/Integer.html#method-i-times

each is an Array/Enumerator method that yields each element.

See:
http://www.ruby-doc.org/core-2.2.0/Array.html#method-i-each
http://www.ruby-doc.org/core-2.0.0/Enumerator.html#method-i-each

Community
  • 1
  • 1
mcls
  • 9,071
  • 2
  • 29
  • 28
  • 1
    Nitpicking, but it doesn't create an array (`to_a` does), it just passes each number to the block. An enumerator is only returned if no block is given. – Stefan Feb 10 '15 at 11:37
2

I assume that i gets initialised to 0. But, how it's getting incremented?

There's an internal variable, the integer itself doesn't change. Let's implement our own times method using a basic while loop:

class Integer
  def my_times
    i = 0            # initialize to 0
    while i < self   # self is the integer object, i.e. 10
      yield i        # pass i to the block
      i += 1         # increment i
    end
  end
end

Usage:

10.my_times { |i| print i, " " } #=> 0 1 2 3 4 5 6 7 8 9

The Ruby method is more complex (returning an enumerator without a block), but you get the idea.

Stefan
  • 109,145
  • 14
  • 143
  • 218
1

In Ruby, everything is an object, including numbers. The integers are objects, meaning, they are defined from an Integer class that contains methods. Those methods can be called on an instance of the object. Thus, the number 10 is an instance object of the Integer class and you can call methods on it.

One of those methods is times. When you do:

10.times ...

You are calling the times method on the object 10. This method accepts a block parameter {...}:

10.times { |i| puts i }

Here, the i is the parameter for the block and the times method internally has a loop that runs that parameter from 0 to the object integer you called the times method on.

As @MarekLipka said in a comment, see the documentation for the Ruby Integer class.

lurker
  • 56,987
  • 9
  • 69
  • 103