In Ruby, a hash is a collection of key-value pairs, where each unique key is associated with a value. It is also known as an associative array or a dictionary in some other programming languages. Hashes are unordered, meaning that the order in which the key-value pairs are stored may not be the same as the order in which they were inserted.

Hashes in Ruby

Here’s the general syntax to define a hash in Ruby:

hash_name = { key1 => value1, key2 => value2, ... }

Let’s examine several demonstration:

Example 1: Basic Hash

person = { "name" => "John", "age" => 30, "city" => "New York" }

In this example, there are three key-value pairs in a hash called person. The keys are strings (“name”, “age”, and “city”), and the corresponding values are “John”, 30, and “New York”, respectively.

Example 2: Symbol Keys

student = { name: "Alice", age: 20, city: "London" }

In Ruby, you can also use symbols as keys in a hash. Symbols are denoted by a colon (:) followed by the symbol name. In this example, we have a hash named student with symbol keys (:name, :age, and :city) and their respective values.

Example 3: Mixed Key Types

book = { title: "Harry Potter", "author" => "J.K. Rowling", year: 2005 }

In this example, we have a hash named book with a mix of symbol keys (:title, :year) and string key (“author”). The corresponding values are “Harry Potter”, “J.K. Rowling”, and 2005, respectively.

To access the values of a hash, you can use square brackets ([]) with the key:

puts person["name"]  # Output: John
puts student[:age]   # Output: 20
puts book[:year]     # Output: 2005

Additionally, you may change a hash’s values or add additional key-value pairs:

person["age"] = 31student[:city] = "Paris"book[:genre] = "Fantasy"

In Ruby, hashes provide a convenient way to store and retrieve data using meaningful keys. They are widely used to represent complex data structures and provide quick access to values based on their associated keys.

Date and time in Ruby

In Ruby, the Date and Time classes are part of the Ruby standard library and provide functionalities for working with dates, times, and time intervals. The Date class handles dates without times, while the Time class represents points in time with both date and time components.

To use the Date and Time classes, you need to require the ‘date’ library at the beginning of your Ruby script:

require 'date'

Now, let’s explore the Date and Time classes with some examples:

Working with Date:

require 'date'

# Current date
today = Date.today
puts today  # Output: 2023-06-14

# Creating a specific date
date = Date.new(2022, 12, 25)
puts date  # Output: 2022-12-25

# Manipulating dates
future_date = today + 7  # Adding 7 days to the current date
puts future_date  # Output: 2023-06-21

past_date = today - 30  # Subtracting 30 days from the current date
puts past_date  # Output: 2023-05-15

# Formatting dates
formatted_date = today.strftime("%d-%m-%Y")
puts formatted_date  # Output: 14-06-2023
require 'date'

# Current date
today = Date.today
puts today  # Output: 2023-06-14

# Creating a specific date
date = Date.new(2022, 12, 25)
puts date  # Output: 2022-12-25

# Manipulating dates
future_date = today + 7  # Adding 7 days to the current date
puts future_date  # Output: 2023-06-21

past_date = today - 30  # Subtracting 30 days from the current date
puts past_date  # Output: 2023-05-15

# Formatting dates
formatted_date = today.strftime("%d-%m-%Y")
puts formatted_date  # Output: 14-06-2023

Working with Time:

# Current time
current_time = Time.now
puts current_time  # Output: 2023-06-14 12:34:56 +0300

# Creating a specific time
time = Time.new(2023, 6, 14, 10, 30, 0)
puts time  # Output: 2023-06-14 10:30:00 +0300

# Manipulating time
future_time = current_time + (60 * 60)  # Adding 1 hour to the current time
puts future_time  # Output: 2023-06-14 13:34:56 +0300

past_time = current_time - (60 * 60 * 24)  # Subtracting 1 day from the current time
puts past_time  # Output: 2023-06-13 12:34:56 +0300

# Formatting time
formatted_time = current_time.strftime("%H:%M:%S")
puts formatted_time  # Output: 12:34:56

The Date and Time classes in Ruby provide a wide range of methods to perform operations such as comparison, parsing, extracting components (day, month, year, hour, etc.), and converting between different formats. They are useful for tasks involving date calculations, scheduling, and working with timestamps.

Ranges of ruby

A range in Ruby denotes a set of numbers with a clear beginning and finish. The ".." may be used to generate ranges. (all possible values) or "…" operator (exclusive range). Ranges may be applied in a number of situations, including iterating through a sequence, determining whether something is included, and obtaining subsets of data.

Here are some examples of using ranges in Ruby:

Example 1: Numeric Range

numeric_range = 1..5
puts numeric_range.include?(3)  # Output: true
puts numeric_range.to_a  # Output: [1, 2, 3, 4, 5]

Here, we define a range of values from 1 to 5 (inclusive). If the range contains the number 3, which is checked, it is true. The to_a function may be used to turn the range into an array, giving us [1, 2, 3, 4, 5].

Example 2: Character Range

char_range = 'a'..'e'
puts char_range.include?('c')  # Output: true
puts char_range.to_a  # Output: ["a", "b", "c", "d", "e"]

Here, we create a range of characters from ‘a’ to ‘e’. We check if the range includes the character ‘c’, which returns true. Converting the range to an array gives [“a”, “b”, “c”, “d”, “e”].

Example 3: String Range

string_range = 'apple'..'banana'
puts string_range.include?('cherry')  # Output: true
puts string_range.to_a  # Output: ["apple", "banana"]

This example demonstrates a range of strings from ‘apple’ to ‘banana’. We check if the range includes the string ‘cherry’, which returns true. Converting the range to an array gives [“apple”, “banana”].

Example 4: Exclusive Range

exclusive_range = 1...5
puts exclusive_range.include?(5)  # Output: false
puts exclusive_range.to_a  # Output: [1, 2, 3, 4]

In this case, we create an exclusive range from 1 to 5. The range includes all values from 1 to 4 but excludes 5. The include?(5) check returns false. Converting the range to an array gives [1, 2, 3, 4].

Ranges in Ruby are versatile and can be used with various types, including numbers, characters, strings, and even custom objects. They provide a concise way to represent and work with sequences of values and are commonly used in iteration, conditional checks, and slicing operations.

Iterators in Ruby

In Ruby, iterators are methods or blocks that allow you to iterate over a collection or perform a repetitive action. They provide a convenient way to traverse and manipulate elements in an array, hash, range, or other enumerable objects.

Ruby provides several built-in iterators that you can use, such as each, map, select, and more. Let’s look at some examples of using iterators in Ruby:

Example 1: each Iterator

fruits = ["apple", "banana", "cherry"]

fruits.each do |fruit|
  puts fruit
end

In this example, the each iterator is used to iterate over each element in the fruits array. The block of code within do and end is executed for each iteration, and the value of the current element is available within the block as fruit. The code simply prints each fruit on a new line.

Example 2: map Iterator

numbers = [1, 2, 3, 4, 5]

squared_numbers = numbers.map do |number|
  number ** 2
end

puts squared_numbers.inspect

Here, the map iterator is used to transform each element of the numbers array by squaring it. The resulting transformed values are collected into a new array named squared_numbers. Finally, inspect is used to display the contents of the squared_numbers array.

Example 3: select Iterator

numbers = [1, 2, 3, 4, 5]

even_numbers = numbers.select do |number|
  number.even?
end

puts even_numbers.inspect

In this example, the select iterator filters the elements of the numbers array and collects only the even numbers into a new array named even_numbers. The block checks if each number is even using the even? method and includes it in the result if true.

Ruby provides many other iterators like each_with_index, reduce, reject, and more. Each iterator has its specific purpose and can make your code more expressive and concise by abstracting away repetitive operations

It’s also worth noting that you can define your own iterators by creating methods or using blocks. This allows you to implement custom iteration behavior tailored to your specific needs.

Iterators are powerful tools in Ruby that simplify working with collections and provide a clean and elegant way to perform operations on elements within those collections.

File I/O in Ruby

In Ruby, File I/O (Input/Output) refers to the process of reading from and writing to files. It allows you to interact with files on your system, such as reading data from a file, writing data to a file, or modifying the contents of a file.

Hashes in Ruby

To work with File I/O in Ruby, you’ll typically use the File class, which provides various methods for file handling. Let’s explore the basic file operations with examples:

1. Opening a File:

The File.open method may be used to open a file. As an argument, you supply the file name (or path) and the mode in which you wish to open the file.

file = File.open("example.txt", "r")  # Open "example.txt" in read mode

2. Reading from a File:

Once a file is open, you can read its contents using various methods. One common method is read, which reads the entire content of the file as a string.

content = file.read
puts content

The read method reads the contents of the file and stores it in the content variable. Then, it prints the content to the console.

3. Writing to a File:

You must open a file in write mode (“w”) in order to write data to it. To write data to the file, use the write or puts method.

file = File.open("example.txt", "w")  # Open "example.txt" in write mode
file.write("Hello, World!")
file.close

We’ll open “example.txt” in write mode in this example (“w”). Next, we write the string “Hello, World!” to the file using the write method. The file is finally closed using the close procedure.

4. Appending to a File:

If you want to append data to an existing file without overwriting its content, you can open the file in append mode (“a”).

file = File.open("example.txt", "a")  # Open "example.txt" in append mode
file.puts("Appended line")
file.close

We open “example.txt” in append mode (“a”) in this example. To add a new line of text to the file, we utilize the puts function. A new line character is immediately added by the puts function. We close the file at this point.

File I/O in Ruby provides additional methods for reading files line by line, checking file existence, renaming files, deleting files, and more. It’s important to close the file after you’re done working with it using the close method to release system resources.

Remember to handle exceptions and errors that may occur during file operations using proper error handling techniques such as begin and rescue blocks.

File I/O allows you to interact with external files, enabling you to read and write data, process large datasets, and perform file manipulations within your Ruby programs.

Exceptions in Ruby

Objects that represent extraordinary circumstances or mistakes made while running a program are known as exceptions in the Ruby programming language. During the course of a program’s execution, unexpected situations may occur. Exceptions offer a means to manage and recover from them.

When an exception is raised, the normal flow of execution is interrupted, and the program looks for an exception handling code block to handle the exception. If no appropriate exception handling is found, the program terminates with an error message.

Here’s an overview of how exceptions work in Ruby along with examples:

1. Raising an Exception:

Using the raise keyword, you may explicitly raise an exception. The raise keyword accepts an optional argument that specifies the kind of exception to be raised as well as an optional message.

raise "This is an exception."

In this example, we raise a generic exception with the message “This is an exception.”

2. Rescuing an Exception:

To handle exceptions, you can use the begin, rescue, and end keywords. The rescue block is used to catch and handle specific exceptions that might be raised within the begin block.

begin
  # Code that might raise an exception
  raise "Exception occurred!"
rescue => e
  # Exception handling code
  puts "Exception handled: #{e.message}"
end

In this illustration, the exception is raised by the raise statement with the message “Exception occurred!” The rescue block then captures the exception and runs the code for managing it. Using e.message, we may retrieve the error message since the => e assigns the exception object to the variable e.

3. Handling Different Types of Exceptions:

You can use multiple rescue blocks to handle different types of exceptions. Each rescue block specifies the type of exception it can handle.

begin
  # Code that might raise exceptions
  raise ArgumentError, "Invalid argument!"
rescue ArgumentError => e
  puts "ArgumentError handled: #{e.message}"
rescue StandardError => e
  puts "StandardError handled: #{e.message}"
end

In this example, the raise statement raises an ArgumentError exception. The first rescue block handles ArgumentError, and the second rescue block handles any other exceptions that are subclasses of StandardError. The appropriate block is executed based on the type of exception raised.

4. Ensuring Cleanup with the ensure Clause:

You can define code that will always be performed using the assure clause, regardless of whether an exception is triggered or not.

begin
  # Code that might raise an exception
  raise "Exception occurred!"
rescue => e
  puts "Exception handled: #{e.message}"
ensure
  puts "Ensure block executed."
end

In this case, regardless of whether an exception is thrown or caught, the assure block will always be run. It may be used to carry out cleaning tasks like resource release or file closure.

Ruby provides a wide range of built-in exception classes, such as StandardError, ArgumentError, TypeError, and more. You can also define your own custom exception classes by subclassing the StandardError class.

By using exceptions, you can gracefully handle and recover from errors and exceptional conditions in your Ruby programs, improving their robustness and reliability.

Categorized in: