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
7: Symbols and Ranges
Up until now, we've been using strings for a lot of our labels. They work, but in a real Ruby codebase, you'll see symbols everywhere. At first glance, a symbol looks like a string with a colon in front of it—:name instead of "name"—but they behave very differently under the hood. Think of a string as a piece of data, while a symbol is more like a name or a label. Because symbols are immutable and unique, Ruby doesn't have to create a new object every time you use one, which makes them faster and more memory-efficient for things like hash keys.
Setting up a Task Tracker with Symbols
Let's build a simple task manager. I want to store tasks where each task has a priority level. Instead of using strings like "High" or "Low", I'm going to use symbols. It just feels more "Ruby-ish" when you're defining a fixed set of options.
task_priorities = {
high: "Immediate attention required",
medium: "Handle this week",
low: "Do it when you have time"
}
puts task_priorities[:high] # Output: Immediate attention required
Notice how I wrote high: in the hash. That's just a shortcut for :high =>. I prefer this syntax; it's cleaner and aligns with how most modern Ruby gems are written.
The "String vs Symbol" Gotcha
Here is where I usually trip up when I'm rushing through a project. I'll be working with a hash and suddenly my code will return nil even though I can clearly see the key exists. Let me show you what I mean.
# I'm trying to access the priority, but I use a string by mistake
priority_key = "high"
puts task_priorities[priority_key] # Output: nil
I just spent five minutes wondering why my hash was "broken" only to realize that :high and "high" are completely different objects to Ruby. The symbol is a unique identifier; the string is just a sequence of characters. To fix this, I have to be consistent. If I'm using symbols as keys, I must use symbols to access them. I'll convert the string to a symbol using the .to_sym method.
priority_key = "high"
puts task_priorities[priority_key.to_sym] # Output: Immediate attention required
Categorizing Scores with Ranges
Now, let's make this more dynamic. Instead of manually assigning a priority, let's say we have a "urgency score" from 1 to 100 and we want to map that score to one of our priority symbols. This is where Ranges come in.
A range in Ruby is defined by two values and a set of dots. 1..10 is inclusive (includes 10), while 1...10 is exclusive (stops at 9). For our priority system, inclusive ranges make the most sense.
def assign_priority(score)
case score
when 80..100
:high
when 40..79
:medium
when 0..39
:low
else
:unknown
end
end
my_score = 85
priority = assign_priority(my_score)
puts "The priority is: #{priority}" # Output: The priority is: high
I love using ranges inside a case statement. It reads almost like a sentence. By returning a symbol from the method, I can then use that symbol to look up the description in my task_priorities hash from earlier. It links the two concepts together perfectly: the range determines the label (symbol), and the symbol retrieves the data.
📋 Practical Task
Build a Temperature Warning System
Your task is to create a script that categorizes temperatures into safety levels. Follow these requirements:
- Create a hash called
warningswhere the keys are symbols (:freezing,:cold,:moderate,:hot) and the values are descriptive strings (e.g.,"Wear a heavy coat!"). - Write a method called
evaluate_tempthat takes a numeric temperature as an argument. - Inside the method, use a
casestatement with Ranges to return the correct symbol based on these brackets:- Below 0:
:freezing - 0 to 15:
:cold - 16 to 25:
:moderate - Above 26:
:hot
- Below 0:
- Call the method with a sample temperature, use the returned symbol to fetch the message from your
warningshash, and print the final message to the console.
There are no comments for now.