Table of contents
1.
Introduction
2.
Statements and control structures
3.
Conditionals
4.
Loops
5.
Iterators and Enumerable objects
6.
Iterators in Ruby
7.
Internal Iterator Vs External Iterators
8.
Iterators and concurrent Modification
9.
Frequently Asked Questions
9.1.
When do we get the ConcurrentModification exception while using an iterator?
9.2.
What are iterators in Ruby?
9.3.
What is Loop in ruby?
9.4.
What is Each_with_Index in ruby?
9.5.
What are data types in ruby?
10.
Conclusion
Last Updated: Mar 27, 2024

Iterators and Concurrent Modification in Ruby

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Ruby is a dynamic, open-source programming language that focuses on productivity and simplicity. The syntax of Ruby is natural and easy to understand for the users. Ruby is a popular language for many things, from web development to data analysis. Ruby programming language is highly flexible, and developers can change how the language works due to its flexibility. Ruby is an interpreted language. 

Ruby

In this article, we will discuss in detail, What are iterators and concurrent modifications in ruby with the help of some examples. So stay till the end; I hope you learn something new from this article. 

Lets get started

Statements and control structures

Program is said to be simple when it is in sequential order, due to which the users are comfortable in understanding the flow of a program. So in this section, we are going to cover Control structures in ruby. 

We are going to cover: Conditionals, Loops, Flow altering statements like return and break, Exceptions, BEGIN and END statements.

So, let us get started with it:

Conditionals

In any programming language, it is seen that the most common control structure is conditionals. 

Conditionals are nothing but the way of telling computers to handle code conditionally: to satisfy some conditions. 

Ruby has abundance of conditionals. We are going to discuss some of them below.

  • if: if is the most straightforward conditional. 


    Syntax:
     
if expression 
  #code 
end

 

  • else: else may be included in the if statement to specify the code to be executed if the conditions are not true.


    Syntax:
     
if expression 
    code 
else 
    code 
end

 

  • elsif: Whenever we want to test multiple conditions, we can add multiple elsif clause between if and else. elsif is a shortened form of “else if”.


    Syntax:
     
if expression1
 code1
elsif expression2 
 code2      
     . 
     . 
elsif expressionN 
 codeN 
else 
 code
end

 

  • ?: operator: The conditional operator ?:, acts similar to an if statement, in which ? is replaced with “then” and : is replaced with “else”.
     
  • case: case in conditional is a multiway statement. It returns the value similar to if the statement does. 

    Syntax:
     
case 
 when x == 1  
  "one" 
 when x == 2   
  "two" 
 when x == 3
  "three" 
end

Loops

Ruby provides different types of loops, such as:

  • for a loop - The for/in loop iterates through the elements of an enumerable object (such as an array). Each iteration assigns an element to a specified loop variable and executes the loop's body. for loop is preferred when we know the number of times loop statements are executed.
     
  • while loop - In a while loop, The condition to be tested is given at the beginning of the loop, and the loop executes the statements until the condition is satisfied. When the condition becomes false, the control goes out. while loop is used when the execution of the statement is not fixed in a program. 
     
  • do-while loop - A do-while loop is similar to a while loop. The only difference is that it checks the condition at last. Therefore even if the condition is false, the loop executes the statements at least once.
     
  • until loop - Until the loop executes the statements until the condition is true, it is the opposite of the while loop as the while loop executes the statements until the condition is false.

Iterators and Enumerable objects

Although loops constitute a significant part of the Ruby language for defining program control structure, it is probably more common to write loops rather than using unique methods called iterators. 

  • Iterators in ruby are one of the most noteworthy features of Ruby which help us in defining the control structure of ruby. 
  • We use the term iterator to mean any yield statement method
  • They do not serve the purpose of an iteration or looping function. 

 

For example, data structures like Array, Hash, Range, and several other classes define each iterator that passes each collection element to the associated block.
 

Similarly, an Enumerable object is one whose purpose is to enumerate over some other object. 

Now that you got a brief understanding of iterators and enumerable objects in ruby, let's get to the main discussion. 

Iterators in Ruby

Iterators are one of the most remarkable features of Ruby. Each map, upto, and times are all iterators and interact with the block of code. Yield is behind the complex control structure. The Iterator simply means to do one thing multiple times. Sometimes iterators are also known as custom loops. 

Iterators are the object-oriented terminology in Ruby, or we can say iterators are the methods supported by collections such as Array, Hashes, etc. Iterators in ruby return all the elements of the collection one by one.

 

Types of iterators present in Ruby are:
 

  • Each Iterator
  • Times Iterator
  • Upto Iterator 
  • Step Iterator
  • Downto Iterator
  • Each_Line Iterator
     

Let us discuss them one by one: 

 

1.Each Iterator

Each Iterator returns all the elements from an array or hash. This iterator returns values one by one.
 

Syntax:

collection.each do |variable_name|
   # code to be iterate
end

 

Example:

(1...6).each do |i|   
   puts i   
end 

 

Output:

1
2
3
4
5

 

2. Times Iterator

In Times Iterator, a loop is embedded a certain number of times. The Loop is started with zero and is executed until one less than the specified number.


Syntax:

t.times do |variable_name|
# code to be executed
end

 

Example:

5.times do |i|
    puts i
end 

 

Output:

0
1
2
3
4

 

3. Upto Iterator

Upto Iterator is known to be following the top to bottom approach. It contains both the top and bottom variables in the iteration.
 

Syntax:

top.upto(bottom) do |variable_name|
# code to execute
end

 

Example:

2.upto(6) do |n|  
  puts n  
end 
 
6.upto(2) do |n|  # here top > bottom # so no output
  puts n  
end

 

Output:

2
3
4
5
6

 

4. Downto Iterator

This Iterator is opposite to the Upto Iterator. In this Iterator, we follow the bottom-to-top approach.
 

Syntax:

top.downto(bottom) do |variable_name|
# code to execute
end

 

Example:

6.downto(2) do |n|  
  puts n  
end 
 
2.downto(6) do |n|  # here top < bottom # so no output
  puts n  
end 

 

Output:

6
5
4
3
2

 

5. Step Iterator

This Iterator is used to iterate in the step where we have to skip a specified range.

 

Syntax:

Collection.step(rng) do |variable_name|
# code to be executed
end 

 

Example:

(0..30).step(5) do|i|
    puts i
end

 

Output:

0
5
10
15
20
25
30

 

6. Each_Line Iterator
This iterator is used to iterate a new line in the given string.

 

Syntax:

string.each_line do |variable_name|
# code to be executed
end

 

Example:

"Welcome\nto\nCoding Ninjas".each_line do|i|
puts i
end

 

Output:

Welcome
to
Coding Ninjas

Internal Iterator Vs External Iterators

We will now learn what Internal Iterator and external Iterator are. The core issue here is to decide which party controls the iteration, the Iterator or the user that uses the Iterator. 
 

Whenever the user handles the iteration, the Iterator is known as External Iterator, and whenever the Iterator controls the iteration, the Iterator is known as Internal Iterator. 

Users that use an external iterator need to advance the traversal and request the next item explicitly from the Iterator.
 

On contrary, in the internal Iterator, the user handover an operator to perform to the internal Iterator, and according to the requirements, the Iterator applies that operation to every item. External iterators are more flexible compared to internal iterators.

Iterators and concurrent Modification

Now, we will understand what iterators and concurrent modifications is with some examples.

In Ruby, its core collection of classes iterate over live objects instead of private copies of those objects; also, they make no effort to detect or prevent concurrent Modification to the collection while its iterated.
 

For example, if you call each method, and block related with that invocation calls the shift method for the same array, the output of the iteration may ve overwhelming:
 

a = [1,2,3,4,5]
a.each {|x| puts "#{x},#{a.shift}" }  # prints "1,1\n3,2\n5,3"

 

Output:

1,1
3,2
5,3


We may see similar behavior if one thread modifies a collection while the other thread is iterating it. The solution to avoid this is to make a copy of the collection before iterating it. 

For example, below code adds a method each_in_snapshot to the Enumerable module:
 

module Enumerable
    def each_in_snapshot &block
        snapshot = self.dup 
        snapshot.each &block
    end
end

 

So, I hope you understand the concept of iterators and concurrent modifications.

Frequently Asked Questions

When do we get the ConcurrentModification exception while using an iterator?

The Iterator will throw this ConcurrentModificationException if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator.

What are iterators in Ruby?

Iterators are the object-oriented concept in Ruby. In simple words, iterators are the methods that are supported by collections(Arrays, Hashes, etc.).

What is Loop in ruby?

Loops in Ruby are used to implement the same block of code a specified number of times.

What is Each_with_Index in ruby?

The each_with_index function in Ruby is used to Iterate over the object with its index and returns the value of the given object. 

What are data types in ruby?

Different types of data types present in ruby are Boolean, Number, String, hashes, Array, Symbols, etc.

Conclusion

In this article, we discussed Iterators and concurrent Modification in ruby in detail with the help of an example. We started with the basic introduction of ruby, then we saw what iterators are in ruby, and then we saw the concept of iterators and concurrent Modification. 

If you want to learn more about such topics, you can see  Introduction to ruby on railsDirectory Structure in RubyRuby on Railsand Ruby vs. Python. Also, refer to the Official Documentation and Ruby Koans. You can explore some more articles on For Loop in RubyOperators in Ruby, or directly access the Coding Ninjas Studio for our courses.

You can also refer to our guided path on Coding Ninjas Studio to upskill yourself in Data structure and algorithmsCompetitive Programming, Javascriptand System Design. Do upvote our blogs if you find them helpful and engaging!

Happy learning!

Ninjas Logo

Live masterclass