Ruby
Printed from:
Ruby Cheatsheet: A Comprehensive Guide
Language Overview
Ruby is a dynamic, object-oriented programming language designed for programmer happiness and productivity. Created by Yukihiro Matsumoto in 1995, Ruby emphasizes the principle of least astonishment (POLA) and follows the philosophy that programming should be fun and intuitive.
Key Characteristics:
- Everything is an object
- Dynamic typing with optional type signatures via RBS
- Interpreted language with a YJIT just-in-time compiler
- Support for functional and meta-programming
- Garbage-collected (generational, incremental)
- Concurrent execution via Ractors and Fibers (non-blocking I/O scheduler)
- Cross-platform compatibility
Basic Syntax
Hello World
12345678910# Simple print statement
puts "Hello, World!"
# Method definition
def greet(name)
"Hello, #{name}!"
end
puts greet("Ruby Developer")
Comments
1234# Single-line comment
=begin
Multiline comment
Can span multiple lines
=end
Data Types
Primitive Types
1234567891011121314151617181920212223# Integer (Fixnum/Bignum unified since 2.4)
age = 30
big_number = 1_000_000 # Underscores for readability
# Float
pi = 3.14159
# Rational and Complex literals
half = 1/2r # (1/2)
imaginary = 2+3i # (2+3i)
# String (frozen string literals recommended)
# frozen_string_literal: true
name = "Ruby"
interpolated = "Hello, #{name}!"
# Boolean
is_true = true
is_false = false
# Nil
nothing = nil
Collection Types
12345678910111213141516171819202122# Array
fruits = ["apple", "banana", "cherry"]
mixed_array = [1, "two", :three]
# Hash (Dictionary) — preserves insertion order
person = {
name: "Alice",
age: 30,
city: "New York"
}
# Hash shorthand (Ruby 3.1+): omit value when key matches local variable
name, age = "Alice", 30
person = { name:, age: } # => { name: "Alice", age: 30 }
# Symbol
status = :active
# Data class (Ruby 3.2+) — immutable value objects
Point = Data.define(:x, :y)
origin = Point.new(x: 0, y: 0)
Variables and Constants
12345678910111213141516# Local variable
local_var = 42
# Instance variable
@instance_var = "I belong to an instance"
# Class variable (use sparingly; prefer class instance variables)
@@class_var = "Shared across all instances"
# Global variable (avoid when possible)
$global_var = "Accessible everywhere"
# Constant
DAYS_IN_WEEK = 7
PI = 3.14159
Operators
Arithmetic Operators
12345678910a = 10
b = 3
puts a + b # Addition: 13
puts a - b # Subtraction: 7
puts a * b # Multiplication: 30
puts a / b # Division: 3
puts a % b # Modulo: 1
puts a ** 2 # Exponentiation: 100
Comparison Operators
1234567891011a = 5
b = 10
puts a == b # Equal to: false
puts a != b # Not equal to: true
puts a < b # Less than: true
puts a > b # Greater than: false
puts a <= b # Less than or equal to: true
puts a >= b # Greater than or equal to: false
puts a <=> b # Spaceship: -1, 0, or 1
Logical Operators
12345678910true_value = true
false_value = false
puts true_value && false_value # Logical AND: false
puts true_value || false_value # Logical OR: true
puts !true_value # Logical NOT: false
# Safe navigation operator (avoid NoMethodError on nil)
user&.profile&.name
Control Structures
Conditional Statements
1234567891011121314151617181920212223242526272829303132333435363738394041# If-else
x = 10
if x > 5
puts "x is greater than 5"
elsif x == 5
puts "x is equal to 5"
else
puts "x is less than 5"
end
# Ternary operator
result = x > 5 ? "Greater" : "Less or Equal"
# Case statement
grade = 'B'
case grade
when 'A'
puts "Excellent!"
when 'B'
puts "Good job!"
when 'C'
puts "Satisfactory"
else
puts "Needs improvement"
end
# Pattern matching with case/in (stable since Ruby 3.0)
config = { host: "localhost", port: 5432 }
case config
in { host: String => host, port: Integer => port }
puts "Connecting to #{host}:#{port}"
in { host: }
puts "Host only: #{host}"
else
puts "Unknown shape"
end
# One-line pattern matching with =>
{ name: "Alice", age: 30 } => { name:, age: }
puts name # "Alice"
Loops
1234567891011121314151617181920212223242526272829# While loop
count = 0
while count < 5
puts count
count += 1
end
# Range iteration (prefer over `for`)
(1..5).each do |num|
puts num
end
# Times loop
5.times do |i|
puts "Iteration #{i}"
end
# Loop control
10.times do |i|
break if i > 5
next if i.even?
puts i
end
# Endless ranges and beginless ranges
(1..).take(5) # [1, 2, 3, 4, 5]
arr = [1, 2, 3, 4, 5]
arr[..2] # [1, 2, 3]
Functions
Basic Functions
123456789101112131415161718192021222324# Method definition
def greet(name = "World")
"Hello, #{name}!"
end
puts greet # "Hello, World!"
puts greet("Ruby") # "Hello, Ruby!"
# Endless method definition (Ruby 3.0+)
def square(x) = x * x
# Keyword arguments
def connect(host:, port: 5432)
"#{host}:#{port}"
end
connect(host: "localhost")
# Multiple return values
def multiple_values
[1, 2, 3]
end
a, b, c = multiple_values
Lambda and Proc
12345678910# Lambda
multiply = ->(x, y) { x * y }
puts multiply.call(3, 4) # 12
puts multiply.(3, 4) # 12
puts multiply[3, 4] # 12
# Proc
multiply_proc = Proc.new { |x, y| x * y }
puts multiply_proc.call(3, 4) # 12
Blocks
123456789101112131415# Block with yield
def demonstrate_block
puts "Before yield"
yield if block_given?
puts "After yield"
end
demonstrate_block { puts "Inside block" }
# Numbered block parameters (Ruby 2.7+)
[1, 2, 3].map { _1 * 2 } # [2, 4, 6]
# `it` block parameter (Ruby 3.4+)
[1, 2, 3].map { it * 2 } # [2, 4, 6]
Object-Oriented Programming
Classes and Objects
12345678910111213141516171819class Person
# Accessor methods
attr_accessor :name, :age
# Constructor
def initialize(name, age)
@name = name
@age = age
end
# Instance method
def introduce
"Hi, I'm #{@name}, #{@age} years old"
end
end
person = Person.new("Alice", 30)
puts person.introduce
Inheritance
12345678910111213class Employee < Person
attr_accessor :company
def initialize(name, age, company)
super(name, age)
@company = company
end
def work_info
"Works at #{@company}"
end
end
Modules and Mixins
1234567891011121314151617181920212223module Swimmable
def swim
"I can swim!"
end
end
class Fish
include Swimmable
end
fish = Fish.new
puts fish.swim # "I can swim!"
# Prepend inserts the module before the class in the ancestor chain
module Logged
def call(*) = (puts "calling"; super)
end
class Service
prepend Logged
def call(*) = "done"
end
Error Handling
12345678910111213141516171819202122232425262728293031323334begin
# Risky code
result = 10 / 0
rescue ZeroDivisionError => e
puts "Error: #{e.message}"
ensure
puts "This always runs"
end
# Method-level rescue
def safe_divide(a, b)
a / b
rescue ZeroDivisionError
Float::INFINITY
end
# Custom exception
class CustomError < StandardError; end
def raise_custom_error
raise CustomError, "Something went wrong"
end
# Exception#cause and #full_message for nested errors
begin
begin
raise "inner"
rescue
raise CustomError, "outer"
end
rescue => e
puts e.full_message
end
File I/O
12345678910111213141516# Writing to a file
File.open("example.txt", "w") do |file|
file.puts "Hello, File!"
end
# Reading from a file
File.read("example.txt")
# Appending to a file
File.open("example.txt", "a") do |file|
file.puts "Another line"
end
# Streaming line by line
File.foreach("example.txt") { |line| puts line }
Concurrency
Threads and Fibers
1234567891011# Threads (share memory, subject to the GVL for CRuby)
threads = 3.times.map { |i| Thread.new { puts "Thread #{i}" } }
threads.each(&:join)
# Fiber scheduler enables non-blocking I/O (Ruby 3.0+)
require "async"
Async do
Async { sleep 1; puts "task 1" }
Async { sleep 1; puts "task 2" }
end
Ractors (experimental, parallel actors)
12345# Ractors enable true parallelism by isolating state (Ruby 3.0+)
r = Ractor.new { Ractor.receive * 2 }
r.send(21)
puts r.take # 42
Type Signatures (RBS)
Ruby ships with RBS, a language for describing types in separate .rbs files.
12345678# person.rbs class Person attr_accessor name: String attr_accessor age: Integer def initialize: (String, Integer) -> void def introduce: () -> String end
Tools: rbs, steep, and typeprof (type inference).
Common Libraries and Frameworks
Standard Library
DateandTimefor date manipulationJSONfor JSON parsingCSVfor CSV file handlingURIfor URI parsingNet::HTTPfor HTTP requestsSetavailable via core (auto-loaded since Ruby 3.2)
Bundled / Default Gems (notable)
bundler— dependency managementirbandreline— interactive shell with multi-line editingdebug— official debugger (replacesbyebug/pry-byebugworkflows)prism— default Ruby parser (replaces Ripper for many tools as of Ruby 3.3+)rbs,typeprof— type toolingerror_highlight,syntax_suggest— friendlier error messagesracc,psych(YAML)
Popular Frameworks and Gems
- Ruby on Rails: Full-stack web framework (Rails 8 introduces Solid Queue/Cache/Cable and Kamal-based deploys)
- Sinatra: Lightweight web framework
- Hanami 2: Modern, modular web framework
- RSpec / Minitest: Testing frameworks
- Sidekiq, Solid Queue, GoodJob: Background job processing
- Rack 3: HTTP server interface
- Puma, Falcon: Application servers
- Standard, RuboCop: Linters and formatters
Best Practices
Code Style
- Use snake_case for variables and method names
- Use CamelCase for class and module names
- Use SCREAMING_SNAKE_CASE for constants
- Prefer
do...endfor multiline blocks and{...}for one-liners - Add
# frozen_string_literal: truemagic comment to source files - Keep methods small and focused
- Use meaningful variable and method names
- Follow the Standard or RuboCop community style guides
Performance Tips
- Enable YJIT in production (
ruby --yjitorRUBY_YJIT_ENABLE=1) for significant speedups - Use
String#freezeorfrozen_string_literal: truefor immutable strings - Prefer
each/map/selectoverforloops - Avoid creating unnecessary intermediate objects (
map+flatten→flat_map) - Use
DataorStructfor simple value objects - Reach for Ractors or processes (not threads) for CPU-bound parallelism on CRuby
Version and Dependency Management
- Use
rbenv,asdf,mise,chruby, orRVMto manage Ruby versions - Use Bundler with a checked-in
Gemfile.lock - Target the latest stable Ruby (3.4.x as of mid-2026); 3.0 reached end-of-life in 2024 and 3.1 in 2025
Testing
12345678910111213141516# RSpec example
RSpec.describe Calculator do
it "adds two numbers" do
expect(Calculator.add(2, 3)).to eq(5)
end
end
# Minitest example (ships with Ruby)
require "minitest/autorun"
class CalculatorTest < Minitest::Test
def test_add
assert_equal 5, Calculator.add(2, 3)
end
end
Resources for Further Learning
- Official Ruby Documentation: https://www.ruby-lang.org/
- Ruby API Reference: https://docs.ruby-lang.org/
- Ruby on Rails Guides: https://guides.rubyonrails.org/
- RubyGems: https://rubygems.org/
- RBS and Steep: https://github.com/ruby/rbs, https://github.com/soutaro/steep
- Standard Style Guide: https://github.com/standardrb/standard
- RuboCop Style Guide: https://github.com/rubocop/ruby-style-guide
Conclusion
Ruby's elegant syntax, powerful object-oriented features, and focus on developer happiness make it a joy to work with. With modern additions like pattern matching, the YJIT compiler, Ractors, and RBS, Ruby continues to evolve while staying true to its philosophy of least astonishment. Embrace it and enjoy writing clean, expressive code!
Continue Learning
Discover more cheatsheets to boost your productivity