DEV Community

🌟🌐 The Ultimate 50-Chapter Guide to Ruby πŸš€

🌟🌐 The Ultimate 50-Chapter Guide to Ruby

Ruby is a dynamic, open-source programming language with a focus on simplicity and productivity. This guide will take you from the basics to advanced concepts over 50 chapters, broken into five parts. Here’s Part 1, covering Chapters 1 to 10.


🌟 Part 1: Getting Started with Ruby – Foundations and Basics


Chapter 1: Introduction to Ruby

Ruby was created by Yukihiro β€œMatz” Matsumoto in the mid-1990s. It combines parts of other programming languages like Perl, Smalltalk, Eiffel, and Ada, emphasizing simplicity and productivity.

Key Features of Ruby

  • Dynamic Typing: You don’t need to declare variable types.
  • Object-Oriented: Everything in Ruby is an object, even numbers and strings.
  • Concise Syntax: Ruby code is clean and easy to read.
  • Rich Libraries: Ruby comes with a robust set of libraries for various tasks.

Example: A Simple Ruby Program

puts "Welcome to Ruby!" 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • puts: A method to print output followed by a newline.
  • "Welcome to Ruby!": A string literal enclosed in double quotes.

Chapter 2: Setting Up Ruby

Step 1: Install Ruby

  1. Use a package manager like RVM (Ruby Version Manager) or rbenv to install Ruby.
 curl -sSL https://get.rvm.io | bash -s stable --ruby 
Enter fullscreen mode Exit fullscreen mode
  1. Verify the installation:
 ruby -v 
Enter fullscreen mode Exit fullscreen mode

Step 2: Install an IDE or Text Editor

  • Popular options: VS Code, Sublime Text, RubyMine.

Step 3: Running Ruby Code

  • Run scripts directly using:
 ruby your_script.rb 
Enter fullscreen mode Exit fullscreen mode
  • Interactive Ruby Shell (IRB):
 irb 
Enter fullscreen mode Exit fullscreen mode

Chapter 3: Ruby Syntax and Basics

Ruby’s syntax is straightforward and resembles natural language.

Key Concepts

  1. Comments:

    • Single-line: # This is a comment
    • Multi-line:
     =begin This is a multi-line comment. =end 
  2. Variables:

    • No need to declare data types.
     name = "Ruby" age = 25 
  3. Printing:

    • puts: Adds a newline after output.
    • print: Outputs without a newline.

Example:

name = "Alice" age = 30 puts "Name: #{name}, Age: #{age}" 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Interpolation: #{} embeds variables or expressions within strings.

Chapter 4: Data Types and Variables

Ruby Data Types

  1. Numbers: Integers and floats.
 a = 10 b = 3.14 
Enter fullscreen mode Exit fullscreen mode
  1. Strings:
 greeting = "Hello" 
Enter fullscreen mode Exit fullscreen mode
  1. Arrays: Ordered collections.
 colors = ["red", "blue", "green"] 
Enter fullscreen mode Exit fullscreen mode
  1. Hashes: Key-value pairs.
 person = { name: "Alice", age: 30 } 
Enter fullscreen mode Exit fullscreen mode

Example: Using Variables

city = "New York" population = 8_500_000 puts "#{city} has a population of #{population}." 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • _ in numbers improves readability.

Chapter 5: Ruby Methods

Defining Methods

def greet(name) puts "Hello, #{name}!" end greet("Ruby") 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Use def to define methods and end to close them.

Returning Values

def square(num) num * num end result = square(4) puts result 
Enter fullscreen mode Exit fullscreen mode

Chapter 6: Conditionals and Loops

Conditionals

age = 18 if age >= 18 puts "Adult" else puts "Minor" end 
Enter fullscreen mode Exit fullscreen mode

Loops

  1. While Loop:
 count = 1 while count <= 5 puts count count += 1 end 
Enter fullscreen mode Exit fullscreen mode
  1. Each Loop:
 [1, 2, 3].each do |num| puts num end 
Enter fullscreen mode Exit fullscreen mode

Chapter 7: Working with Strings

Ruby provides powerful methods for string manipulation.

Key Methods

  1. Concatenation:
 full_name = "Alice" + " " + "Smith" 
Enter fullscreen mode Exit fullscreen mode
  1. Interpolation:
 greeting = "Hello, #{full_name}" 
Enter fullscreen mode Exit fullscreen mode
  1. Methods:
 str = " hello world " puts str.strip.upcase.reverse 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • strip: Removes whitespace.
  • upcase: Converts to uppercase.
  • reverse: Reverses the string.

Chapter 8: Arrays and Their Operations

Creating Arrays

fruits = ["apple", "banana", "cherry"] 
Enter fullscreen mode Exit fullscreen mode

Common Operations

  1. Accessing Elements:
 puts fruits[0] # apple 
Enter fullscreen mode Exit fullscreen mode
  1. Adding Elements:
 fruits.push("date") 
Enter fullscreen mode Exit fullscreen mode
  1. Iterating:
 fruits.each { |fruit| puts fruit } 
Enter fullscreen mode Exit fullscreen mode

Chapter 9: Hashes – Key-Value Pairs

Creating Hashes

person = { name: "Alice", age: 30 } 
Enter fullscreen mode Exit fullscreen mode

Accessing Values

puts person[:name] # Alice 
Enter fullscreen mode Exit fullscreen mode

Adding/Updating

person[:city] = "New York" 
Enter fullscreen mode Exit fullscreen mode

Chapter 10: Object-Oriented Programming Basics

Ruby is a true object-oriented language.

Defining a Class

class Person attr_accessor :name, :age def initialize(name, age) @name = name @age = age end def greet puts "Hello, my name is #{@name}." end end alice = Person.new("Alice", 30) alice.greet 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • initialize: Constructor method.
  • @: Instance variable.
  • attr_accessor: Creates getter and setter methods.

Conclusion of Part 1

In Part 1, we covered the foundational concepts of Ruby, including syntax, data types, conditionals, loops, and basic object-oriented programming. These are the building blocks you’ll need as we dive into more advanced topics in Part 2.

Let me know when you're ready for Part 2!

🌟 Part 2: Intermediate Ruby Concepts – Expanding the Toolkit

In Part 2, we dive deeper into Ruby by covering intermediate topics essential for becoming a proficient Ruby developer. This part focuses on advanced data structures, error handling, file manipulation, and more.


Chapter 11: Advanced String Manipulation

Ruby provides a rich library for working with strings beyond basic operations.

String Interpolation

You can embed Ruby code directly into strings.

name = "Ruby" puts "Welcome to #{name.upcase} programming!" 
Enter fullscreen mode Exit fullscreen mode

String Methods

  1. Splitting Strings:
 sentence = "Ruby is fun" words = sentence.split(" ") puts words.inspect # ["Ruby", "is", "fun"] 
Enter fullscreen mode Exit fullscreen mode
  1. Joining Strings:
 joined = words.join("-") puts joined # Ruby-is-fun 
Enter fullscreen mode Exit fullscreen mode
  1. Checking Substrings:
 puts sentence.include?("fun") # true 
Enter fullscreen mode Exit fullscreen mode
  1. Regular Expressions:
 email = "user@example.com" puts email.match?(/\A\w+@\w+\.\w+\z/) # true 
Enter fullscreen mode Exit fullscreen mode

Chapter 12: Working with Symbols

Symbols are immutable, lightweight strings often used as keys in hashes or identifiers.

Creating Symbols

status = :active puts status.class # Symbol 
Enter fullscreen mode Exit fullscreen mode

Symbols vs. Strings

  • Symbols are immutable and faster for comparisons.
  • Strings are mutable but heavier.

Example: Hash Keys

user = { name: "Alice", status: :active } puts user[:status] # active 
Enter fullscreen mode Exit fullscreen mode

Chapter 13: Advanced Arrays

Common Array Operations

  1. Map: Transforms elements in an array.
 numbers = [1, 2, 3] squares = numbers.map { |n| n * n } puts squares.inspect # [1, 4, 9] 
Enter fullscreen mode Exit fullscreen mode
  1. Select: Filters elements based on a condition.
 even_numbers = numbers.select { |n| n.even? } puts even_numbers.inspect # [2] 
Enter fullscreen mode Exit fullscreen mode
  1. Reduce: Aggregates elements to a single value.
 sum = numbers.reduce(0) { |sum, n| sum + n } puts sum # 6 
Enter fullscreen mode Exit fullscreen mode

Chapter 14: Nested Data Structures

You can create complex structures like arrays of hashes or hashes of arrays.

Example: Array of Hashes

users = [ { name: "Alice", age: 25 }, { name: "Bob", age: 30 } ] users.each do |user| puts "#{user[:name]} is #{user[:age]} years old." end 
Enter fullscreen mode Exit fullscreen mode

Example: Hash of Arrays

grades = { math: [90, 80, 85], science: [88, 92, 84] } grades.each do |subject, marks| average = marks.sum / marks.size puts "#{subject.capitalize}: #{average}" end 
Enter fullscreen mode Exit fullscreen mode

Chapter 15: Error Handling

Ruby has a robust system for handling errors using the begin-rescue block.

Example: Basic Error Handling

begin result = 10 / 0 rescue ZeroDivisionError => e puts "Error: #{e.message}" end 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • begin: Start the block of code.
  • rescue: Catch errors.
  • e.message: Access error details.

Ensure and Retry

begin file = File.open("nonexistent.txt") rescue Errno::ENOENT puts "File not found!" ensure puts "This will run regardless of an error." end 
Enter fullscreen mode Exit fullscreen mode

Chapter 16: File Handling

Ruby makes it easy to read and write files.

Reading Files

File.open("example.txt", "r") do |file| file.each_line { |line| puts line } end 
Enter fullscreen mode Exit fullscreen mode

Writing Files

File.open("example.txt", "w") do |file| file.puts "Hello, Ruby!" end 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Modes: "r" (read), "w" (write), "a" (append).

Chapter 17: Blocks and Procs

Blocks are chunks of code that can be passed to methods.

Using Blocks

def greet yield("Alice") end greet { |name| puts "Hello, #{name}!" } 
Enter fullscreen mode Exit fullscreen mode

Procs

Procs are saved blocks.

hello_proc = Proc.new { |name| puts "Hello, #{name}!" } hello_proc.call("Ruby") 
Enter fullscreen mode Exit fullscreen mode

Chapter 18: Lambdas

Lambdas are similar to Procs but enforce argument checking.

Example

square = ->(n) { n * n } puts square.call(4) # 16 
Enter fullscreen mode Exit fullscreen mode

Chapter 19: Modules

Modules group related methods and constants.

Example

module MathUtils def self.square(n) n * n end end puts MathUtils.square(5) # 25 
Enter fullscreen mode Exit fullscreen mode

Mixins

module Greetings def say_hello puts "Hello!" end end class Person include Greetings end person = Person.new person.say_hello 
Enter fullscreen mode Exit fullscreen mode

Chapter 20: Ruby Gems and Bundler

Ruby Gems

Gems are packages of Ruby code.

  1. Install a Gem:
 gem install rails 
Enter fullscreen mode Exit fullscreen mode
  1. Using Gems:
 require "json" puts JSON.generate({ name: "Ruby" }) 
Enter fullscreen mode Exit fullscreen mode

Bundler

Manages dependencies.

gem install bundler 
Enter fullscreen mode Exit fullscreen mode

Create a Gemfile:

source "https://rubygems.org" gem "sinatra" 
Enter fullscreen mode Exit fullscreen mode

Install dependencies:

bundle install 
Enter fullscreen mode Exit fullscreen mode

Conclusion of Part 2

This section expanded on foundational Ruby concepts, introducing intermediate tools like advanced data structures, error handling, file manipulation, and gems. You're now ready for more advanced topics in Part 3, where we'll dive into metaprogramming, advanced OOP, and working with databases.

Let me know when you're ready for Part 3!

🌟 Part 3: Advanced Ruby Concepts – Mastering the Language

In Part 3, we delve into advanced Ruby concepts, focusing on topics like metaprogramming, advanced object-oriented programming (OOP), multithreading, working with APIs, and managing databases. By the end of this part, you'll be well-equipped to build powerful Ruby applications.


Chapter 21: Metaprogramming Basics

Metaprogramming allows Ruby code to write or modify itself dynamically, enabling powerful abstractions.

Dynamic Methods

You can define methods at runtime using define_method.

class DynamicClass [:hello, :goodbye].each do |method_name| define_method(method_name) do |name| puts "#{method_name.capitalize}, #{name}!" end end end obj = DynamicClass.new obj.hello("Alice") # Hello, Alice! obj.goodbye("Bob") # Goodbye, Bob! 
Enter fullscreen mode Exit fullscreen mode

method_missing

Intercept calls to undefined methods.

class DynamicResponder def method_missing(method_name, *args) puts "You called #{method_name} with arguments: #{args.inspect}" end end obj = DynamicResponder.new obj.any_method("arg1", "arg2") 
Enter fullscreen mode Exit fullscreen mode

respond_to_missing?

Complement method_missing for introspection.

class DynamicResponder def respond_to_missing?(method_name, include_private = false) method_name.to_s.start_with?("any_") || super end end 
Enter fullscreen mode Exit fullscreen mode

Chapter 22: Advanced Object-Oriented Programming (OOP)

Inheritance and Polymorphism

Use inheritance to share functionality across classes.

class Animal def speak "I am an animal." end end class Dog < Animal def speak "Woof! Woof!" end end animal = Animal.new dog = Dog.new puts animal.speak # I am an animal. puts dog.speak # Woof! Woof! 
Enter fullscreen mode Exit fullscreen mode

Modules as Mixins

module Swimmable def swim "I'm swimming!" end end class Fish include Swimmable end fish = Fish.new puts fish.swim 
Enter fullscreen mode Exit fullscreen mode

Chapter 23: Reflection in Ruby

Reflection allows introspection of objects, classes, and methods at runtime.

Inspecting Methods

class Sample def example; end end sample = Sample.new puts sample.methods.grep(/example/) # [:example] 
Enter fullscreen mode Exit fullscreen mode

Getting Class and Instance Variables

class Person @class_var = "class level" def initialize(name) @name = name end end puts Person.instance_variables # [:@class_var] puts Person.new("Alice").instance_variables # [:@name] 
Enter fullscreen mode Exit fullscreen mode

Chapter 24: Ruby and APIs

Ruby has excellent support for working with APIs, especially with libraries like Net::HTTP and HTTParty.

Fetching Data with Net::HTTP

require "net/http" require "json" url = URI("https://jsonplaceholder.typicode.com/posts/1") response = Net::HTTP.get(url) post = JSON.parse(response) puts post["title"] 
Enter fullscreen mode Exit fullscreen mode

Using HTTParty

Install the gem:

gem install httparty 
Enter fullscreen mode Exit fullscreen mode

Example:

require "httparty" response = HTTParty.get("https://jsonplaceholder.typicode.com/posts/1") puts response.parsed_response["title"] 
Enter fullscreen mode Exit fullscreen mode

Chapter 25: Working with Databases

Ruby provides tools like SQLite3 and ActiveRecord for interacting with databases.

Using SQLite3

Install the gem:

gem install sqlite3 
Enter fullscreen mode Exit fullscreen mode

Example:

require "sqlite3" db = SQLite3::Database.new "test.db" db.execute "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)" db.execute "INSERT INTO users (name) VALUES (?)", ["Alice"] rows = db.execute "SELECT * FROM users" puts rows.inspect 
Enter fullscreen mode Exit fullscreen mode

Using ActiveRecord

gem install activerecord gem install sqlite3 
Enter fullscreen mode Exit fullscreen mode

Example setup:

require "active_record" ActiveRecord::Base.establish_connection( adapter: "sqlite3", database: "db.sqlite3" ) class User < ActiveRecord::Base; end User.create(name: "Alice") puts User.all.inspect 
Enter fullscreen mode Exit fullscreen mode

Chapter 26: Ruby Threads and Concurrency

Ruby supports multithreading for concurrent programming.

Creating Threads

thread1 = Thread.new { 5.times { puts "Thread 1"; sleep 1 } } thread2 = Thread.new { 5.times { puts "Thread 2"; sleep 1 } } thread1.join thread2.join 
Enter fullscreen mode Exit fullscreen mode

Thread Safety

Use mutexes to prevent race conditions.

mutex = Mutex.new counter = 0 threads = 10.times.map do Thread.new do mutex.synchronize do counter += 1 end end end threads.each(&:join) puts counter # 10 
Enter fullscreen mode Exit fullscreen mode

Chapter 27: Ruby Enumerators

Enumerators provide an advanced way to handle collections.

Creating Enumerators

enumerator = (1..5).each puts enumerator.next # 1 puts enumerator.next # 2 
Enter fullscreen mode Exit fullscreen mode

Chaining Enumerators

result = (1..10).select(&:even?).map { |n| n * 2 } puts result.inspect # [4, 8, 12, 16, 20] 
Enter fullscreen mode Exit fullscreen mode

Chapter 28: Ruby DSLs (Domain-Specific Languages)

Ruby is widely used for creating DSLs, like RSpec or Rails routes.

Example: Simple DSL

class HTML def self.generate(&block) instance = new instance.instance_eval(&block) end def tag(name, content) puts "<#{name}>#{content}</#{name}>" end end HTML.generate do tag :h1, "Welcome to Ruby DSLs!" tag :p, "This is an example paragraph." end 
Enter fullscreen mode Exit fullscreen mode

Chapter 29: Working with JSON and YAML

JSON

require "json" data = { name: "Ruby", version: "3.2" } json = JSON.generate(data) puts json parsed = JSON.parse(json) puts parsed["name"] 
Enter fullscreen mode Exit fullscreen mode

YAML

require "yaml" data = { name: "Ruby", version: "3.2" } yaml = data.to_yaml puts yaml parsed = YAML.load(yaml) puts parsed["name"] 
Enter fullscreen mode Exit fullscreen mode

Chapter 30: Ruby Performance Optimization

Benchmarking

Use Benchmark to measure performance.

require "benchmark" time = Benchmark.measure do 100_000.times { "Ruby".upcase } end puts time 
Enter fullscreen mode Exit fullscreen mode

Avoiding Common Bottlenecks

  • Use lazy enumerators for large datasets.
 result = (1..Float::INFINITY).lazy.select(&:even?).first(10) puts result.inspect # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] 
Enter fullscreen mode Exit fullscreen mode

Conclusion of Part 3

This part covered advanced Ruby features like metaprogramming, multithreading, API integration, and database handling. You’re now well-equipped to tackle challenging problems with Ruby.

Let me know when you're ready for Part 4!

🌟 Part 4: Ruby in Practice – Advanced Applications

Part 4 dives deeper into practical applications of Ruby, focusing on advanced techniques, real-world applications, and optimizing Ruby for scalability. By the end of this section, you’ll have practical insights into applying Ruby to solve complex problems.


Chapter 31: Ruby on Rails – Introduction and Overview

Ruby on Rails (RoR) is a popular framework for building web applications. It emphasizes convention over configuration, making development faster and more efficient.

What is Ruby on Rails?

Rails is a full-stack web framework built on Ruby, offering tools for database management, web servers, and front-end integrations.

Creating Your First Rails App

  1. Install Rails:
 gem install rails 
Enter fullscreen mode Exit fullscreen mode
  1. Create a new Rails application:
 rails new my_app cd my_app 
Enter fullscreen mode Exit fullscreen mode
  1. Run the server:
 rails server 
Enter fullscreen mode Exit fullscreen mode

Access your app at http://localhost:3000.

Key Components of Rails

  • Models: Handle database interactions.
  • Views: Render HTML and front-end content.
  • Controllers: Manage application logic.

Example – Scaffold a Blog Post

rails generate scaffold Post title:string content:text rails db:migrate 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • This generates a basic CRUD (Create, Read, Update, Delete) interface for managing posts.
  • rails db:migrate applies changes to your database schema.

Chapter 32: Testing in Ruby with RSpec

RSpec is a popular testing library in Ruby, designed for behavior-driven development (BDD).

Installing RSpec

Add RSpec to your project:

gem install rspec 
Enter fullscreen mode Exit fullscreen mode

Writing Your First Test

Create a file spec/sample_spec.rb:

RSpec.describe "Math Operations" do it "adds two numbers" do expect(2 + 3).to eq(5) end end 
Enter fullscreen mode Exit fullscreen mode

Run tests with:

rspec 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • describe groups related tests.
  • it defines an individual test case.
  • expect is used to define expectations.

Advanced Example: Testing a Class

class Calculator def add(a, b) a + b end end RSpec.describe Calculator do it "adds two numbers correctly" do calc = Calculator.new expect(calc.add(2, 3)).to eq(5) end end 
Enter fullscreen mode Exit fullscreen mode

Chapter 33: Advanced File and Directory Handling

Ruby provides robust tools for handling files and directories.

Working with Files

File.open("example.txt", "w") do |file| file.puts "Hello, Ruby!" end content = File.read("example.txt") puts content # Output: Hello, Ruby! 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • File.open creates or opens a file.
  • "w" mode writes data to the file.
  • File.read retrieves the file content.

Directory Management

Dir.mkdir("new_folder") unless Dir.exist?("new_folder") Dir.chdir("new_folder") do File.open("file.txt", "w") { |file| file.puts "In a new folder!" } end 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Dir.mkdir creates directories.
  • Dir.chdir changes the working directory temporarily.

Chapter 34: Advanced Regular Expressions in Ruby

Ruby's regex capabilities are powerful for pattern matching and string manipulation.

Regex Basics

text = "Hello, Ruby World!" puts text.scan(/\b\w+\b/) # ["Hello", "Ruby", "World"] 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • \b matches word boundaries.
  • \w+ matches one or more word characters.

Replacing Text with Regex

text = "Price: $100" updated_text = text.gsub(/\$\d+/, "$200") puts updated_text # Price: $200 
Enter fullscreen mode Exit fullscreen mode

Validation with Regex

email = "user@example.com" valid = email.match?(/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i) puts valid # true 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • \A and \z mark the start and end of the string.
  • \w+ matches alphanumeric characters.
  • @ ensures the email structure.

Chapter 35: Ruby Gems – Creating and Using Custom Gems

Ruby Gems are reusable libraries packaged for easy sharing.

Using Existing Gems

Add the gem to your Gemfile:

gem 'nokogiri' 
Enter fullscreen mode Exit fullscreen mode

Run:

bundle install 
Enter fullscreen mode Exit fullscreen mode

Example using Nokogiri for HTML parsing:

require "nokogiri" html = "<h1>Hello World</h1>" doc = Nokogiri::HTML(html) puts doc.at('h1').text # Hello World 
Enter fullscreen mode Exit fullscreen mode

Creating a Custom Gem

  1. Create the structure:
 bundle gem my_custom_gem 
Enter fullscreen mode Exit fullscreen mode
  1. Implement functionality in lib/my_custom_gem.rb.
  2. Build the gem:
 gem build my_custom_gem.gemspec 
Enter fullscreen mode Exit fullscreen mode
  1. Install locally:
 gem install my_custom_gem 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Gems make it easy to share functionality across projects.
  • Gemspec defines metadata like name, version, and dependencies.

Chapter 36: Ruby and Network Programming

Ruby makes it simple to build networked applications.

Creating a Simple TCP Server

require "socket" server = TCPServer.new(3000) loop do client = server.accept client.puts "Hello, Client!" client.close end 
Enter fullscreen mode Exit fullscreen mode

Creating a TCP Client

require "socket" socket = TCPSocket.new("localhost", 3000) puts socket.gets # Hello, Client! socket.close 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • TCPServer listens for incoming connections.
  • TCPSocket connects to a server.

Chapter 37: Ruby and Web Scraping

Ruby makes web scraping accessible with libraries like Nokogiri.

Scraping Example

require "nokogiri" require "open-uri" url = "https://example.com" doc = Nokogiri::HTML(URI.open(url)) puts doc.at("h1").text 
Enter fullscreen mode Exit fullscreen mode

Handling CSS Selectors

titles = doc.css(".article-title").map(&:text) puts titles 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • URI.open fetches the HTML.
  • Nokogiri::HTML parses the HTML for easy manipulation.

Chapter 38: Ruby's Enumerator Class

Enumerators handle lazy evaluation, making them efficient for large datasets.

Lazy Evaluation Example

enum = (1..Float::INFINITY).lazy.select { |x| x % 2 == 0 }.first(5) puts enum.inspect # [2, 4, 6, 8, 10] 
Enter fullscreen mode Exit fullscreen mode

Chaining Methods

result = (1..100).map { |x| x * 2 }.select { |x| x > 50 } puts result 
Enter fullscreen mode Exit fullscreen mode

Chapter 39: Debugging Ruby Code

Ruby provides tools like byebug for debugging.

Installing byebug

gem install byebug 
Enter fullscreen mode Exit fullscreen mode

Debugging Example

require "byebug" def calculate(a, b) byebug a + b end puts calculate(2, 3) 
Enter fullscreen mode Exit fullscreen mode

Chapter 40: Optimizing Ruby for Performance

Profile Code Execution

Use the benchmark library:

require "benchmark" time = Benchmark.measure do 100_000.times { "ruby".upcase } end puts time 
Enter fullscreen mode Exit fullscreen mode

Avoid Common Bottlenecks

  • Use efficient data structures like hashes and arrays.
  • Avoid unnecessary object allocations.
  • Leverage lazy evaluation for large data streams.

Conclusion of Part 4

You’ve mastered advanced applications of Ruby, including Rails, testing, and network programming. Let me know when you're ready for Part 5!

The Ultimate 50-Chapter Guide to Ruby

🌟 Part 5: Mastering Ruby – Expert-Level Concepts and Practices

Part 5 will focus on the expert-level features of Ruby, enabling you to master its intricacies, optimize your applications, and tackle complex challenges. These chapters cover Ruby's metaprogramming capabilities, internal architecture, memory optimization, multithreading, and more.


Chapter 41: Ruby Metaprogramming – Unlocking the Power of Code

Metaprogramming allows Ruby to write or modify its code during runtime, offering unparalleled flexibility.

What is Metaprogramming?

Metaprogramming manipulates Ruby's methods, classes, and modules dynamically. It's often used to reduce repetitive code or create highly dynamic systems.

Dynamic Method Creation

class DynamicMethods [:method1, :method2, :method3].each do |method_name| define_method(method_name) do puts "You called #{method_name}!" end end end obj = DynamicMethods.new obj.method1 # Output: You called method1! 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • define_method dynamically creates methods with the given name.
  • It reduces redundancy when creating similar methods.

Open Classes

Ruby classes are open, meaning you can modify them at runtime.

class String def shout self.upcase + "!!!" end end puts "hello".shout # Output: HELLO!!! 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Adding a method to the String class customizes its behavior.
  • Use this carefully to avoid unintentional side effects.

Method Missing

Intercept undefined method calls with method_missing.

class Proxy def method_missing(name, *args) puts "You tried to call #{name} with #{args.inspect}" end end obj = Proxy.new obj.unknown_method(1, 2, 3) # Output: You tried to call unknown_method with [1, 2, 3] 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • This is useful for dynamic delegation or error handling.
  • Always pair method_missing with respond_to_missing?.

Chapter 42: Ruby's Object Model

Ruby's object model defines how classes, objects, and modules interact internally.

Everything is an Object

puts 42.is_a?(Object) # true puts "Hello".is_a?(Object) # true puts nil.is_a?(Object) # true 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • In Ruby, even primitives like integers and nil are objects.

Singleton Classes

Singleton classes are used to define behavior unique to a single object.

obj = "Hello" def obj.shout self.upcase + "!!!" end puts obj.shout # Output: HELLO!!! 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Adding methods directly to an object impacts only that object.
  • Useful for defining custom behavior on the fly.

Ancestor Chain

Every class in Ruby has an inheritance hierarchy.

puts String.ancestors.inspect # Output: [String, Comparable, Object, Kernel, BasicObject] 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • The ancestor chain determines method lookup order.
  • Ruby searches each module/class sequentially.

Chapter 43: Ruby’s Memory Model

Understanding memory management is crucial for optimizing Ruby applications.

Garbage Collection

Ruby uses a garbage collector (GC) to manage memory.

ObjectSpace.each_object(String) { |s| puts s } 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • ObjectSpace inspects Ruby's memory.
  • Avoid creating excessive objects to reduce GC overhead.

Optimizing Object Allocation

Minimize object creation to save memory.

# Inefficient 100_000.times { |i| "string #{i}" } # Efficient shared_string = "string" 100_000.times { |i| "#{shared_string} #{i}" } 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Reusing objects reduces memory usage.
  • String interpolation ("#{}) is faster than concatenation (+).

Chapter 44: Multithreading in Ruby

Ruby supports multithreading for concurrent operations.

Creating Threads

threads = [] 5.times do |i| threads << Thread.new { puts "Thread #{i} running" } end threads.each(&:join) 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Thread.new creates a new thread.
  • join waits for the thread to complete.

Thread Safety

Use Mutex to avoid race conditions.

mutex = Mutex.new counter = 0 threads = 5.times.map do Thread.new do mutex.synchronize { counter += 1 } end end threads.each(&:join) puts counter # Output: 5 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • synchronize ensures only one thread accesses the critical section at a time.

Chapter 45: Ruby and Concurrency – Fibers

Fibers provide lightweight concurrency, useful for non-blocking operations.

Using Fibers

fiber = Fiber.new do puts "Fiber started" Fiber.yield puts "Fiber resumed" end fiber.resume # Fiber started fiber.resume # Fiber resumed 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Fiber.yield pauses execution.
  • resume restarts the fiber.

Chapter 46: Ruby for Data Science

Ruby can handle data manipulation with libraries like Daru and Numo.

DataFrames with Daru

require "daru" data = Daru::DataFrame.new({ name: ["Alice", "Bob"], age: [25, 30], score: [85, 90] }) puts data 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Daru::DataFrame organizes tabular data.
  • Useful for data manipulation and analysis.

Chapter 47: Ruby and Machine Learning

While not as common as Python, Ruby has ML libraries like sciruby.

Basic ML with Ruby

require "nmatrix" matrix = NMatrix.new([2, 2], [1, 2, 3, 4]) puts matrix.transpose.inspect 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • NMatrix handles numerical computations.
  • Ruby's ecosystem for ML is growing but limited compared to Python.

Chapter 48: Building Ruby DSLs

Ruby’s syntax makes it ideal for creating Domain-Specific Languages (DSLs).

Example DSL

class FormBuilder def initialize @fields = [] end def field(name, type) @fields << { name: name, type: type } end def render @fields.map { |f| "#{f[:name]}: #{f[:type]}" }.join("\n") end end form = FormBuilder.new form.field "username", "text" form.field "password", "password" puts form.render 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • DSLs simplify specific tasks by offering a clean, domain-specific interface.

Chapter 49: Ruby and Blockchain

Ruby can be used to implement blockchain basics.

Basic Blockchain Example

require "digest" class Block attr_reader :data, :previous_hash, :hash def initialize(data, previous_hash) @data = data @previous_hash = previous_hash @hash = Digest::SHA256.hexdigest(data + previous_hash.to_s) end end block1 = Block.new("Block 1", "0") block2 = Block.new("Block 2", block1.hash) puts block2.hash 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Each block contains data, a previous hash, and a current hash.
  • Digest::SHA256 generates unique hashes for blocks.

Chapter 50: Ruby for Game Development

Ruby is used in 2D game development with libraries like Gosu.

Basic Game with Gosu

require "gosu" class Game < Gosu::Window def initialize super 640, 480 self.caption = "My Game" end def draw Gosu.draw_rect(10, 10, 100, 100, Gosu::Color::WHITE) end end Game.new.show 
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Gosu::Window creates a game window.
  • draw renders game elements.

Conclusion of Part 5

Part 5 provides deep insights into Ruby’s advanced features, from metaprogramming to concurrency. Let me know when you're ready for more Ruby mastery!
Plz follow me for more and leave reactions and comments

Top comments (1)