Page Content

Tutorials

What Is Mean By Iterators In Ruby And Types Of Iterators

Iterators in Ruby

In Ruby programming, iterators are a fundamental idea that are commonly used in place of more traditional loop statements like while and for. An iterator in Ruby is a unique type of method that mostly functions as a loop and works closely with a block of code that comes after it.

The Core Mechanism: and Blocks

Iterators are made possible by the yield statement.

Control Flow: Control is momentarily returned to the block of code linked to the method invocation from the iterator method by the yield statement.

Looping: The yield statement is usually called several times by an iterator method in order to implement a looping structure.

Returning Control: Execution restarts at the statement just after yield, and the iterator method automatically regains control when the block is finished.

Passing Values: The yield statement can be followed by expressions to pass values from the iterator to the block. These values are allocated to parameters that are indicated by vertical bars (|…|) and defined at the beginning of the block.

The keywords do and end or curly brackets ({}) can be used to delimit a section of code. For simple, single-line blocks, curly brackets are utilised, whereas the doend syntax is typically chosen for multi-line blocks.

You can also read What Is Mean By Operators In Ruby, It’s Types With Examples

Types of Iterators

Generally speaking, iterators are categorised according to the section of code that governs the iteration:

Internal Iterators (The Ruby Default)

The iterator method itself rules this style and “pushes” values to the block that is attached. It includes the majority of conventional Ruby iterators.

Numeric Iterators

There are numerous frequently used iterators defined by the Integer class:

Iterator MethodDescriptionCode ExampleOutputSource
timesInvokes the block $N$ times, passing values 0 through $N-1$.3.times { print "Ruby! " }Ruby! Ruby! Ruby!
uptoCounts up from the receiver to the argument, including both endpoints.`1.upto(3) {xprint x }`
downtoIterates downwards from the receiver to the argument.`5.downto(1) {nprint n }`

Collection Iterators (each and Enumerable Methods)

Each, the most popular iterator, calls the corresponding block once for every element in the collection (such as an array, hash, or range).

The Enumerable module is frequently included in classes that specify an each method, and each of these classes gains over 20 iteration-related methods (such as collect, select, inject, and sort) built upon it.

Iterator MethodDescriptionCode ExampleOutput/ResultSource
eachPasses each element of the collection to the block.`.each {xprint x*2 }`
collect (or map)Executes the block for each element and collects the block’s return values into a new array.`.collect {xx*x}`
selectReturns an array of elements for which the block returns a value that is not false or nil.`(1..10).select {xx%2 == 0}`
injectAccumulates a value across iterations, returning the final accumulated value.data = `data.inject {sum, xsum + x }`

Writing a Custom Internal Iterator (using yield)

You can use the yield statement to define your own iterator methods. This approach frequently behaves like a custom loop since it anticipates a block and calls it again.

def sequence(n, m, c)
  i = 0
  while(i < n)      # Loop n times
    yield m*i + c   # Invoke the block, and pass a value to it
    i += 1          # Increment i each time
  end
end

# Invocation:
sequence(3, 5, 1) {|y| puts y }

Output

1
6
11

A while loop is used internally in the implementation of this sequence method, and yield is called to pass calculated values to the corresponding block.

External Iterators (Enumerators)

Enumerating another object is the main function of an enumerator, which is an enumerable object. Because Enumerators are built into Ruby 1.9 and act as external iterators, client code can use the next function to sequentially “pull” values. In contrast, the method pushes values to the block in internal iterators.

An Enumerator object can be obtained by using methods such as to_enum or enum_for, or by executing an iterator method without providing a block.

Example of an External Iterator (Pulling values):

The next function is repeatedly used by the external iterator model until a StopIteration exception is raised, signifying the end of the sequence. This exception is implicitly rescued for simple looping by the Kernel.loop method.

iterator = 9.downto(1)             # An enumerator as external iterator 

loop do                            # Loop until StopIteration is raised
  print iterator.next              # Call the next method repeatedly 
  
end
puts "...blastoff!"

Output

987654321...blastoff!

The rewind method can be used to resume external iterators (albeit usually not a continuous file stream, provided the underlying source permits it, such as a Range or Array).

Example of a Custom Enumerator (for infinite streams):

An unending stream of values can be defined with enumerators.

fibonacci = Enumerator.new do |yielder|
  a, b = 0, 1
  loop do
    yielder << a
    a, b = b, a + b
  end
end

# This line now prints the output
puts fibonacci.take(10).inspect

Output

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

You can also read Conditional Statements In Ruby: A Control Flow Techniques

Agarapu Geetha
Agarapu Geetha
My name is Agarapu Geetha, a B.Com graduate with a strong passion for technology and innovation. I work as a content writer at Govindhtech, where I dedicate myself to exploring and publishing the latest updates in the world of tech.
Index