Skip to content

cheatnotes/ruby-cheatsheet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

RUBY PROGRAMMING COMPREHENSIVE CHEATSHEET

Comprehensive Ruby cheatsheet covering syntax, data types, OOP, modules, blocks, exceptions, file I/O, regex, Enumerable, and common gems. Includes naming conventions, operators, loops, hashes, arrays, and practical code examples—perfect for beginners and experienced devs needing quick reference.

Table of Contents

  1. Basic Syntax & Execution
  2. Data Types
  3. Variables & Constants
  4. Operators
  5. Conditionals
  6. Loops & Iterators
  7. Arrays
  8. Hashes
  9. Strings
  10. Symbols
  11. Methods (Functions)
  12. Classes & Objects (OOP)
  13. Modules & Mixins
  14. Blocks, Procs & Lambdas
  15. Exception Handling
  16. File I/O
  17. Regular Expressions
  18. Enumerable Module
  19. Common Gems
  20. Ruby Style Guide

1. Basic Syntax & Execution

# Single line comment

=begin
Multi-line comment
=end

# Print with newline
puts "Hello World"

# Print without newline
print "Hello"

# Print with inspect (useful for debugging)
p "Hello"  # => "Hello"

# Get user input
name = gets.chomp

# Execute: ruby filename.rb
# Interactive: irb or pry

2. Data Types

# Numbers
integer = 42
float = 3.14
big_num = 1_000_000_000  # underscores for readability

# Boolean
true_obj = true
false_obj = false
nil_obj = nil  # represents "nothing" (falsey)

# Strings
str = "double quotes - interpolation: #{2 + 2}"
str2 = 'single quotes - literal: #{2 + 2}'

# Symbols (immutable, memory efficient)
symbol = :name
:hello == "hello".to_sym

# Arrays
arr = [1, 2, 3, "four", :five]

# Hashes
hash = { name: "Alice", age: 30 }  # Ruby 1.9+ syntax
old_hash = { :name => "Bob", :age => 25 }

# Ranges
range = 1..10   # inclusive
range2 = 1...10  # exclusive (10 not included)

3. Variables & Constants

# Variable naming conventions
local_var = "lowercase with underscores"     # local variable
@instance_var = "starts with @"              # instance variable
@@class_var = "starts with @@"               # class variable
$global_var = "starts with $"                # global variable
CONSTANT = "ALL_CAPS"                        # constant (warning if reassigned)

# Parallel assignment
a, b, c = 1, 2, 3
x, y = [10, 20]  # x=10, y=20

# Swap variables
a, b = b, a

# Variable existence
defined? some_var  # returns nil if not defined

4. Operators

# Arithmetic
+  -  *  /  %  **  # add, subtract, multiply, divide, modulo, exponent

# Comparison
==   !=   >   <   >=   <=   <=>  # <=> returns -1, 0, or 1

# Logical
&&   ||   !    # logical and, or, not
and  or  not   # lower precedence versions

# Assignment shortcuts
x += 5   # x = x + 5
x -= 2
x *= 3
x /= 2
x %= 4
x **= 2

# Special operators
defined?  # check if variable/method defined
..  ...    # range operators
&  |  ^    # bitwise AND, OR, XOR
<<  >>     # bitwise shift

# Safe navigation (Ruby 2.3+)
user&.address&.city  # returns nil if any part missing

5. Conditionals

# If/else
if condition
  # code
elsif other_condition
  # code
else
  # code
end

# Inline if
puts "Yes" if x > 10

# Unless (opposite of if)
unless condition
  # runs if condition is false
end

# Inline unless
puts "No" unless x > 10

# Ternary
result = age >= 18 ? "Adult" : "Minor"

# Case statement
case grade
when "A"
  puts "Excellent"
when "B", "C"
  puts "Good"
else
  puts "Try harder"
end

# Case with expressions
case
when score > 90
  puts "A"
when score > 80
  puts "B"
end

6. Loops & Iterators

# While loop
while condition
  # code
end

# Until loop
until condition
  # code
end

# For loop (rarely used, prefer iterators)
for i in 1..5
  puts i
end

# Times iterator
5.times { |i| puts i }       # 0,1,2,3,4

# Each iterator (most common)
[1,2,3].each { |num| puts num }
(1..5).each do |num|
  puts num
end

# Other iterators
array.each_with_index { |val, idx| puts "#{idx}: #{val}" }
array.map { |x| x * 2 }       # transform
array.select { |x| x.even? }  # filter
array.reject { |x| x.odd? }   # opposite of select

# Loop control
break   # exit loop
next    # skip to next iteration
redo    # repeat current iteration
retry   # restart loop (begin/rescue)

# Infinite loop
loop do
  puts "forever"
  break if condition
end

7. Arrays

# Creation
arr = Array.new(3)        # [nil, nil, nil]
arr = Array.new(3, "x")   # ["x", "x", "x"]
arr = %w[apple banana]    # ["apple", "banana"]
arr = %i[name age]        # [:name, :age]

# Access
arr[0]        # first element
arr[-1]       # last element
arr[1..3]     # range
arr[1, 3]     # start, length

# Modification
arr << 4                 # push
arr.push(5)
arr.unshift(0)           # prepend
arr.pop                  # remove last
arr.shift                # remove first
arr.delete(3)            # delete all 3's
arr.delete_at(2)         # delete index 2
arr.insert(2, 'new')     # insert at index

# Combination
arr1 + arr2              # concatenation
arr1 - arr2              # difference
arr1 & arr2              # intersection
arr1 | arr2              # union

# Useful methods
arr.length               # size
arr.empty?
arr.include?(5)
arr.flatten              # flatten nested arrays
arr.uniq                 # remove duplicates
arr.sort
arr.reverse
arr.sample               # random element
arr.shuffle
arr.join(", ")           # to string

# Array destructuring
first, *rest = [1, 2, 3, 4]  # first=1, rest=[2,3,4]

8. Hashes

# Creation
hash = { name: "Alice", age: 30 }
hash = Hash.new(default_value)
hash = Hash[:a, 1, :b, 2]

# Access
hash[:name]        # "Alice"
hash.fetch(:name)  # with error handling
hash[:missing]     # nil
hash.dig(:a, :b)   # nested hash access

# Modification
hash[:city] = "NYC"
hash.delete(:age)
hash.merge!(other_hash)  # destructive merge

# Iteration
hash.each { |key, value| puts "#{key}: #{value}" }
hash.each_key { |key| puts key }
hash.each_value { |value| puts value }

# Transform
hash.map { |k, v| [k.to_s, v] }.to_h
hash.select { |k, v| v > 18 }
hash.transform_values { |v| v * 2 }

# Default values
hash = Hash.new(0)           # default 0 for missing keys
hash = Hash.new { |h, k| h[k] = [] }  # auto-vivification

# Useful methods
hash.key?(:name)   # check key
hash.value?("Alice")
hash.invert        # swap keys and values
hash.keys
hash.values
hash.length

9. Strings

# Interpolation
name = "Ruby"
puts "Hello #{name}"          # Hello Ruby
puts %Q(Hello #{name})        # alternative
puts %(Hello #{name})         # same

# Special syntax
%q(no interpolation)          # like single quotes
%w(word1 word2)               # array of words
%W(word1 #{name})             # interpolated words

# Manipulation
str = "Hello World"
str.length            # 11
str.upcase            # "HELLO WORLD"
str.downcase
str.capitalize
str.reverse
str.strip             # remove whitespace
str.chomp             # remove newline
str.gsub("World", "Ruby")
str.sub("World", "Ruby")      # first occurrence

# Slicing
str[0]                # "H"
str[0,5]              # "Hello"
str[6..10]            # "World"
str["World"]          # "World"
str[/[A-Z]/]          # "H"

# Splitting/Joining
str.split(" ")        # ["Hello", "World"]
words.join("-")       # "Hello-World"

# Predicates
str.empty?
str.include?("World")
str.start_with?("Hello")
str.end_with?("World")

# Formatting
"%.2f" % 3.1415       # "3.14"
"%03d" % 5            # "005"
"Name: %s, Age: %d" % ["Bob", 25]

# Escaping
puts "Quote: \"Hello\""
puts 'It\'s Ruby'

10. Symbols

# Creation
sym = :name
sym = :"name with spaces"

# Properties
:name.object_id == :name.object_id  # true (immutable)
"name".object_id == "name".object_id  # false

# Conversion
:name.to_s           # "name"
"name".to_sym        # :name

# Use cases
# As hash keys (more efficient than strings)
hash = { :name => "Alice" }  # old syntax
hash = { name: "Alice" }     # new syntax

hash = Hash[[:a, 1], [:b, 2]]

# As method arguments
attr_reader :name, :age

# Checking existence
Symbol.all_symbols.include?(:name)

11. Methods (Functions)

# Basic method
def greet(name)
  return "Hello, #{name}"
end

# Implicit return (last expression)
def add(a, b)
  a + b
end

# Default arguments
def greet(name = "World")
  puts "Hello, #{name}"
end

# Keyword arguments
def create_user(name:, age: 18, city: "NYC")
  { name: name, age: age, city: city }
end
create_user(name: "Alice", city: "LA")

# Variable arguments (*splat)
def sum(*numbers)
  numbers.sum
end
sum(1,2,3,4)  # 10

# Double splat for keyword args
def process(**options)
  options.each { |k,v| puts "#{k}: #{v}" }
end

# Method with block
def repeat(n)
  n.times { yield if block_given? }
end
repeat(3) { puts "Hi" }

# Predicate method (returns boolean)
def even?(num)
  num % 2 == 0
end

# Dangerous/Bang method (modifies object)
def upcase!
  @name = @name.upcase
end

# Method alias
alias new_name old_name

# Method visibility (in classes)
private
protected
public

12. Classes & Objects (OOP)

# Basic class
class Person
  # Attributes
  attr_accessor :name, :age    # getter + setter
  attr_reader :id              # getter only
  attr_writer :secret          # setter only

  # Class variable
  @@population = 0

  # Constant
  SPECIES = "Homo sapiens"

  # Constructor
  def initialize(name, age)
    @name = name
    @age = age
    @@population += 1
  end

  # Instance method
  def introduce
    "I'm #{@name}, #{@age} years old"
  end

  # Class method
  def self.population
    @@population
  end

  # To string
  def to_s
    "Person: #{@name}"
  end

  # Equality
  def ==(other)
    @name == other.name && @age == other.age
  end
end

# Inheritance
class Student < Person
  def initialize(name, age, grade)
    super(name, age)   # call parent constructor
    @grade = grade
  end

  # Override
  def introduce
    super + " and I'm a student"
  end
end

# Usage
alice = Person.new("Alice", 30)
puts alice.name          # getter
alice.age = 31           # setter
puts alice.introduce
puts Person.population

# Class with metaclass methods
class MathUtils
  class << self
    def square(x)
      x * x
    end
  end
end

# Singleton methods (on a single object)
str = "Hello"
def str.shout
  upcase + "!!!"
end

13. Modules & Mixins

# Module as namespace
module MathUtils
  PI = 3.14159
  def self.square(x)
    x * x
  end
end
MathUtils.square(5)   # 25

# Module as mixin (include)
module Swimmable
  def swim
    "Swimming!"
  end
end

module Flyable
  def fly
    "Flying!"
  end
end

class Duck
  include Swimmable
  include Flyable
end

duck = Duck.new
duck.swim   # "Swimming!"
duck.fly    # "Flying!"

# Module with instance methods
module Serializable
  def to_json
    instance_variables.each_with_object({}) do |var, hash|
      hash[var.to_s.delete('@')] = instance_variable_get(var)
    end.to_json
  end
end

# Extend (adds class methods)
module ClassMethods
  def create
    new
  end
end

class Product
  extend ClassMethods
end

Product.create   # class method

# Prepend (overrides methods)
module Logger
  def save
    puts "Logging before save"
    super
    puts "Logging after save"
  end
end

class Document
  prepend Logger
  def save
    puts "Saving document"
  end
end
# Outputs: Logging before save, Saving document, Logging after save

# Include vs Prepend vs Extend
# include: adds as superclass (instance methods)
# prepend: adds before class (overrides)
# extend: adds class methods

14. Blocks, Procs & Lambdas

# Blocks (anonymous, not objects)
def perform
  puts "Before"
  yield if block_given?
  puts "After"
end

perform { puts "Inside block" }

# Block with parameters
def with_params
  yield(5, 10)
end

with_params { |a, b| puts a + b }

# Procs (blocks as objects)
my_proc = Proc.new { |x| puts x * 2 }
my_proc = proc { |x| puts x * 2 }  # shorthand
my_proc.call(5)                     # 10
my_proc[5]                          # 10
my_proc === 5                       # 10 (case w/ procs)

# Lambdas (more strict than procs)
my_lambda = lambda { |x| puts x * 2 }
my_lambda = ->(x) { puts x * 2 }    # stabby lambda
my_lambda.call(5)

# Differences between Proc and Lambda
# 1. Lambda checks argument count, Proc doesn't
lambda { |x| x }.call(1,2)  # Error
proc { |x| x }.call(1,2)    # Ignores extra args

# 2. Return behavior
def test_proc
  proc { return "from proc" }.call
  "after proc"
end

def test_lambda
  lambda { return "from lambda" }.call
  "after lambda"
end

test_proc   # => "from proc" (returns from method)
test_lambda # => "after lambda"

# Passing blocks to methods
def each_with_custom_block(&block)
  [1,2,3].each(&block)
end

# Converting symbol to proc
[1,2,3].map(&:to_s)  # ["1","2","3"]

15. Exception Handling

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

# Multiple rescues
begin
  file = File.open("missing.txt")
rescue Errno::ENOENT => e
  puts "File not found"
rescue StandardError => e
  puts "Other error: #{e.class}"
end

# Ensure (always runs)
begin
  file = File.open("data.txt")
  # process file
rescue
  puts "Error occurred"
ensure
  file.close if file
end

# Raising exceptions
def validate_age(age)
  raise ArgumentError, "Age must be positive" if age <= 0
end

# Custom exception
class MyCustomError < StandardError
  attr_reader :code

  def initialize(message, code)
    super(message)
    @code = code
  end
end

# Retry
attempts = 0
begin
  attempts += 1
  risky_operation
rescue NetworkError
  retry if attempts < 3
end

# Else clause
begin
  # code that might raise
rescue
  # error handling
else
  # runs if no exception
end

# Rescue modifier
result = risky_operation rescue "default value"

16. File I/O

# Reading files
File.open("file.txt", "r") do |file|
  content = file.read
  lines = file.readlines
end

# Shortcuts
content = File.read("file.txt")
lines = File.readlines("file.txt")

# Writing files
File.open("output.txt", "w") do |file|
  file.write("Hello World\n")
  file.puts("Another line")
end

# Append mode
File.open("log.txt", "a") do |file|
  file.puts("New log entry")
end

# Shortcut write
File.write("file.txt", "content")

# File operations
File.exist?("file.txt")
File.delete("file.txt")
File.rename("old.txt", "new.txt")
File.size("file.txt")
File.directory?("dir")
File.file?("file.txt")

# Directory operations
Dir.mkdir("new_dir")
Dir.delete("empty_dir")
Dir.entries(".")           # list contents
Dir.glob("*.rb")           # match files
Dir["*.{rb,erb}"]          # multiple patterns

# Working with paths
require 'pathname'
path = Pathname.new("folder/file.txt")
path.basename      # "file.txt"
path.dirname       # "folder"
path.extname       # ".txt"
path.absolute?
path = Pathname.pwd + "new_file.txt"

# IO streams
$stdin      # standard input
$stdout     # standard output
$stderr     # standard error
STDIN.gets
STDOUT.puts "message"

17. Regular Expressions

# Creation
regex = /pattern/
regex = %r{pattern}
regex = Regexp.new("pattern")

# Matching
if "Hello World" =~ /World/
  puts "Match found"
end

# Match operator
match = "Ruby 2.7" =~ /\d+\.\d+/  # returns index
match = /World/.match("Hello World")

# MatchData object
match = /(\w+):\s(\d+)/.match("Age: 25")
match[0]      # "Age: 25" (full match)
match[1]      # "Age"
match[2]      # "25"
match[:key]   # named capture

# Named captures
pattern = /(?<name>\w+):\s(?<age>\d+)/
match = pattern.match("Bob: 30")
match[:name]  # "Bob"
match[:age]   # "30"

# Scan (find all matches)
"one two three".scan(/\w+/)  # ["one","two","three"]
"a1 b2 c3".scan(/(\w)(\d)/)  # [["a","1"],["b","2"],["c","3"]]

# Substitution
"Hello World".sub(/World/, "Ruby")    # "Hello Ruby"
"Hello World".gsub(/[aeiou]/, '*')    # "H*ll* W*rld"

# Split
"one,two,three".split(/,/)  # ["one","two","three"]

# Common patterns
/\d+/       # digits
/\w+/       # word characters
/\s+/       # whitespace
/./         # any character
/^/         # start of line
/$/         # end of line
/[aeiou]/   # character class
/[^aeiou]/  # negated class
/\A/        # start of string
/\z/        # end of string

# Options
/pattern/i   # case insensitive
/pattern/m   # multiline
/pattern/x   # extended (ignore whitespace)

18. Enumerable Module

# Each (base iterator)
[1,2,3].each { |x| puts x }

# Map / Collect (transform)
[1,2,3].map { |x| x * 2 }        # [2,4,6]
(1..5).collect { |x| x ** 2 }    # [1,4,9,16,25]

# Select / Find All (filter)
[1,2,3,4,5].select { |x| x.even? }  # [2,4]

# Reject (opposite of select)
[1,2,3].reject { |x| x > 2 }        # [1,2]

# Detect / Find (first match)
[1,2,3].find { |x| x > 1 }          # 2

# Reduce / Inject (accumulate)
[1,2,3,4].reduce(0) { |sum, n| sum + n }  # 10
[1,2,3].inject(:*)                           # 6

# Any? / All? / None? / One? (predicates)
[1,2,3].any?(&:even?)      # true (at least one even)
[1,2,3].all?(&:even?)      # false
[1,2,3].none?(&:even?)     # false
[1,2,3].one?(&:even?)      # false (two evens)

# Group By
[1,2,3,4].group_by(&:even?)  # {true=>[2,4], false=>[1,3]}

# Partition
[1,2,3,4].partition(&:even?)  # [[2,4], [1,3]]

# Sort
[3,1,4,2].sort                              # [1,2,3,4]
[3,1,4,2].sort_by { |x| -x }               # [4,3,2,1]

# Chaining
[1,2,3,4,5]
  .select(&:even?)
  .map { |x| x * 10 }
  .reduce(:+)  # 2*10 + 4*10 = 60

# Lazy evaluation (for large collections)
(1..Float::INFINITY)
  .lazy
  .select(&:even?)
  .first(5)  # [2,4,6,8,10]

19. Common Gems

# In Gemfile or install: gem install <name>

# Pry (better IRB)
require 'pry'
binding.pry  # start debugger

# HTTP requests
require 'httparty'
response = HTTParty.get('https://api.example.com')
response.body
response.code

# JSON parsing
require 'json'
hash = JSON.parse('{"name":"Alice"}')
json = {name: "Bob"}.to_json

# Database (ActiveRecord)
require 'active_record'
ActiveRecord::Base.establish_connection(
  adapter: 'sqlite3',
  database: 'db.sqlite3'
)

class User < ActiveRecord::Base
end

# Testing (RSpec)
# spec/my_spec.rb
RSpec.describe "Example" do
  it "works" do
    expect(2 + 2).to eq(4)
  end
end

# Web framework (Sinatra)
require 'sinatra'
get '/' do
  "Hello World"
end

# Web scraping (Nokogiri)
require 'nokogiri'
doc = Nokogiri::HTML(html_string)
doc.css('a').each { |link| puts link['href'] }

# File utilities (FileUtils)
require 'fileutils'
FileUtils.cp('src.txt', 'dest.txt')
FileUtils.mkdir_p('path/to/dir')
FileUtils.rm_rf('directory')

# Date/Time (ActiveSupport)
require 'active_support/all'
1.day.ago
3.hours.from_now
Date.today.beginning_of_week

20. Ruby Style Guide

# Naming
# snake_case for methods and variables
# CamelCase for classes and modules
# SCREAMING_SNAKE_CASE for constants

# Spacing
# 2 spaces indentation (no tabs)
def method
  if condition
    do_something
  end
end

# Method parentheses
# Omit when no arguments
def greet
  puts "hello"
end

# Use when arguments
def add(a, b)
  a + b
end

# Hash syntax
# Use 1.9+ style when keys are symbols
{ name: "Alice", age: 30 }

# String literals
# Prefer single quotes unless interpolation needed
name = 'Ruby'
puts "Hello #{name}"  # interpolation requires double

# Conditional modifiers
puts "Yes" if condition  # inline when short
# Use block form for multi-line

# Avoid `for` loops (use each)
# Avoid `and`/`or` (use `&&`/`||`)

# Use `each` without block returns Enumerator
# Use `map` instead of `collect`
# Use `select` instead of `find_all`

# Freeze mutable constants
ARRAY = [1,2,3].freeze

# Use `%w` for word arrays
%w[apple banana cherry]

# Use `%i` for symbol arrays
%i[name age city]

# Use `_` for unused block parameters
hash.each { |key, _| puts key }

# Comment style
# Single line comment with space after #
# FIXME: fix this later
# TODO: implement this

# Magic comment for UTF-8 encoding
# frozen_string_literal: true
# coding: utf-8

Quick Reference Tips

Task Ruby Code
Run Ruby file ruby filename.rb
Interactive shell irb or pry
Install gem gem install gem_name
Check version ruby -v
Syntax check ruby -c filename.rb
Debug mode ruby -r debug filename.rb
Watch file ruby -w filename.rb

Key Ruby Principles

  1. Everything is an object - even numbers, classes, and nil
  2. Duck typing - "If it walks like a duck..."
  3. Open classes - modify existing classes at runtime
  4. Method missing - powerful metaprogramming
  5. Blocks everywhere - Ruby's secret sauce

About

Comprehensive Ruby cheatsheet covering syntax, data types, OOP, modules, blocks, exceptions, file I/O, regex, Enumerable, and common gems. Includes naming conventions, operators, loops, hashes, arrays, and practical code examples—perfect for beginners and experienced devs needing quick reference.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Generated from cheatnotes/cheatnotes