Ruby
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Methods and Blocks
-
Section 4: Object-Oriented Ruby
-
Section 5: Metaprogramming
-
Section 6: Working with Data and Files
-
Section 7: Ruby Frameworks Overview
-
Section 8: Ecosystem and Testing
-
Section 9: Practical Projects
-
Section 10: Interview Practice
-
Section 11: Data Structures and Algorithms in Ruby
-
Section 12: More Practice Exercises
-
Section 13: Enumerable and Functional Style
-
Section 14: More OOP Practice
-
Section 15: More Testing
-
Section 16: Enumerable and Comparable Modules In Depth
-
Section 17: Ruby Standard Library: Core Utilities
-
Section 18: Ruby Standard Library: Data and Security
-
Section 19: Ruby Standard Library: CLI and Text
-
Section 20: Ruby Networking
-
Section 21: Ruby on Rails Deep Dive
-
Section 22: Ruby Metaprogramming Deep Dive
-
Section 23: Ruby Design Patterns
-
Section 24: Ruby Concurrency
-
Section 25: Ruby Testing Deep Dive
-
Section 26: Ruby Gems and Packaging
-
Section 27: Ruby Performance
-
Section 28: More Practice Exercises
-
Section 29: More Interview Practice
-
Section 30: Rails API Development
-
Section 31: Rails Authentication and Authorization
-
Section 32: Rails Testing Deep Dive
-
Section 33: Rails Performance
-
Section 34: Rails Deployment
-
Section 35: Sinatra and Lightweight Ruby Web Apps
-
Section 36: More Ruby Language Deep Dive
-
Section 37: Ruby 3.x Modern Features
-
Section 38: More Data Structures in Ruby
-
Section 39: More Practical Projects
-
Section 40: Ruby Ecosystem Tools
-
Section 41: More Practice and Review
-
Section 42: Final Practice and Mastery
-
Section 43: Ruby Interview Deep Dive
-
Section 44: Ruby Background Processing Deep Dive
-
Section 45: Ruby GraphQL
-
Section 46: Ruby Object Model Deep Dive
-
Section 47: Ruby Hanami Framework Overview
-
Section 48: Ruby gRPC and Protocol Buffers
-
Section 49: Ruby Data Processing
-
Section 50: Ruby Search Integration
-
Section 51: Ruby File Upload and Media
-
Section 52: Ruby Email and Notifications
-
Section 53: Ruby Admin Panels
-
Section 54: Ruby Feature Flags and Experimentation
-
Section 55: Ruby Monitoring and Observability
-
Section 56: Ruby Docker and Deployment Deep Dive
-
Section 57: Ruby Security Deep Dive
-
Section 58: More Advanced Metaprogramming
-
Section 59: More Final Projects
80: URI Module for Parsing URLs
I've seen this happen more times than I can count: a developer needs to grab a specific piece of data from a URL, and their first instinct is to treat that URL as a simple string. It seems harmless enough until the edge cases hit you like a ton of bricks.
# The "Quick and Dirty" approach that will eventually break
url = "https://api.service.com:8080/v1/search?q=ruby+uri&limit=10#results"
# I just want the domain and the search query
domain = url.split('/')[2]
query_string = url.split('?')[1].split('&')[0].split('=')[1]
puts "Domain: #{domain}" # "api.service.com:8080" (Wait, I wanted just the host!)
puts "Query: #{query_string}" # "ruby+uri" (Wait, it's still URL-encoded!)
The Fragility of String Splitting
The code above looks like it works for a moment, but it's a landmine. Notice how the domain includes the port :8080? If you were trying to compare that domain against a whitelist, your check would fail. Even worse, the query value is ruby+uri. In a real application, you can't just leave the + or %20 characters in there; you need the actual decoded string.
Then there's the fragment #results. If the URL didn't have a query string but did have a fragment, url.split('?')[1] would return nil, and your app would crash with a NoMethodError. You can't possibly write enough if/else statements to cover every permutation of a valid URI.
Letting the URI Module Handle the Heavy Lifting
Ruby comes with a built-in URI module specifically designed to tear these strings apart according to RFC standards. Instead of guessing where the slashes and question marks are, you wrap the string in a URI object.
require 'uri'
url_string = "https://api.service.com:8080/v1/search?q=ruby+uri&limit=10#results"
uri = URI.parse(url_string)
puts uri.scheme # => "https"
puts uri.host # => "api.service.com" (No port here!)
puts uri.port # => 8080
puts uri.path # => "/v1/search"
puts uri.query # => "q=ruby+uri&limit=10"
puts uri.fragment # => "results"
See how much cleaner that is? uri.host gives you exactly the domain, stripped of the port and the protocol. I personally love how this turns a messy string into a structured object with named methods. It makes your intent clear to anyone else reading your code.
Handling the Query Hash
While uri.query is great, it still returns a string. You almost never want to manually split that string again. Instead, use URI.decode_www_form. This method takes that query string and turns it into an array of arrays, which you can easily convert into a hash.
# Turning the query string into a usable Ruby Hash
params = URI.decode_www_form(uri.query).to_h
puts params["q"] # => "ruby uri" (Automatically decoded!)
puts params["limit"] # => "10"
One quick tip: URI.parse will throw a URI::InvalidURIError if the string is completely malformed. In a production environment, I always wrap my parsing in a begin/rescue block if the URL is coming from an untrusted user input. You don't want a typo in a URL to bring down your entire worker process.
📋 Practical Task
Build a Website Metadata Extractor
Create a script that takes an array of complex URLs and extracts a "Clean Summary" for each one. Your script should process the following list:
urls = [
"https://blog.ruby-lang.org/en/entries/123?utm_source=twitter&ref=nav#comments",
"http://dev.example.com:3000/projects/ruby-uri/wiki?action=edit&user=admin",
"https://shop.store.com/items/search?category=books&sort=price_asc"
]
For each URL, your program must output a string in this exact format:
"Host: [host] | Path: [path] | First Param: [first_param_key]=[first_param_value]"
Requirements:
- Use
URI.parseto extract the host and path. - Use
URI.decode_www_formto access the query parameters. - Ensure that the first parameter value is properly decoded (e.g., spaces instead of
+). - Handle the output for all three URLs in the array.
There are no comments for now.