-
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
46: Practice Exercise: Building a Simple CSV Report Generator
When you first need to get some data into a spreadsheet, it's tempting to treat a CSV as just a text file where things are separated by commas. I've seen a lot of developers—myself included, early in my career—take the "quick and dirty" route by just interpolating strings. It feels efficient because you aren't loading a library or learning a new API; you're just manipulating strings, which you already know how to do.
The temptation of string interpolation
Imagine we're building a simple report that exports a list of users and their subscription plans. A naive implementation usually looks something like this:
users = [
{ name: "Alice Smith", plan: "Premium", email: "alice@example.com" },
{ name: "Bob Jones", plan: "Basic", email: "bob@example.com" }
]
csv_string = "Name,Plan,Email\n"
users.each do |user|
csv_string += "#{user[:name]},#{user[:plan]},#{user[:email]}\n"
end
File.write("report.csv", csv_string)
On the surface, this works. If your data is clean and predictable, you've got a CSV file in five lines of code. But in a production environment, "clean and predictable" data is a myth. This approach assumes that none of your data fields will ever contain a comma, a newline, or a double quote.
Where the string approach falls apart
Here is where things get messy. What happens when a user signs up as "Company, Inc."? Or what if a field contains a quoted string? If you use the string interpolation method above, a name like "Company, Inc." will be written into the file as Company, Inc.,Premium,email@example.com. When you open that in Excel or Google Sheets, the "Inc." gets pushed into the "Plan" column, and everything shifts one cell to the right. Your report is now corrupted.
You could try to fix this by writing your own regex to find commas and wrap them in quotes, but that's a rabbit hole you don't want to go down. You'd essentially be rewriting a CSV parser from scratch, and you'll almost certainly miss an edge case that will crash a client's import script three months from now.
Leveraging the CSV standard library
The professional way to handle this in Ruby is to use the built-in CSV library. It doesn't just join strings; it handles the RFC 4180 standard, which means it knows exactly how to escape quotes and handle commas within values. I prefer using CSV.open because it streams the data to the file rather than building one massive string in memory, which is critical if you're ever exporting thousands of rows.
require 'csv'
users = [
{ name: "Company, Inc.", plan: "Premium", email: "contact@corp.com" },
{ name: "Bob \"The Builder\" Jones", plan: "Basic", email: "bob@example.com" }
]
CSV.open("report.csv", "wb") do |csv|
# Write the header row
csv << ["Name", "Plan", "Email"]
# Write the data rows
users.each do |user|
csv << [user[:name], user[:plan], user[:email]]
end
end
Notice the difference in the logic. Instead of worrying about delimiters and newlines, you're simply passing an array of values to the csv object. The library handles the heavy lifting: "Company, Inc." will be automatically wrapped in double quotes in the final file, and the double quotes in Bob's nickname will be properly escaped. It's cleaner, it's safer, and it's the way you'll see it done in any serious Ruby codebase.
📋 Practical Task
Exercise: Build an Inventory Audit Export Tool
Your task is to create a script that generates an inventory report for a warehouse. You must use the CSV library to ensure the data is formatted correctly, as some of the product names contain characters that would break a naive string-based implementation.
Requirements:
- Create an array of hashes representing products. Each product should have a
name,sku, anddescription. - Include at least one product name that contains a comma (e.g., "Widget, Deluxe Edition").
- Include at least one description that contains double quotes (e.g., "Known as the \"Gold Standard\" of widgets").
- Write the data to a file named
inventory_audit.csv. - The CSV must have a header row:
Product Name, SKU, Description.
Once you've run your script, open the resulting inventory_audit.csv in a text editor to verify that the library automatically added quotes around the fields containing commas and handled the internal quotes correctly.
There are no comments for now.