C
h
i
L
L
u
.
.
.
Dynamic Programming Language

The Complete Ruby Language Guide

Master Ruby — the elegant, expressive language designed for programmer happiness, powering Ruby on Rails and thousands of web applications.

Why Learn Ruby?

Ruby was created by Yukihiro "Matz" Matsumoto and released in 1995. Matz designed Ruby to make programming fun and to prioritize the developer's experience over machine efficiency. The language follows the principle of least surprise — it behaves the way an experienced programmer would expect.

Ruby gained massive popularity through Ruby on Rails, a web framework that transformed how web applications are built. Rails' "convention over configuration" philosophy enables rapid development, powering GitHub, Shopify, Airbnb, and Basecamp.

Ruby is fully object-oriented — everything is an object, including numbers, strings, and even nil. This consistency makes it remarkably readable and expressive.

Ruby philosophy: "Ruby is designed to make programmers happy." — Matz

1. Ruby Basics & Syntax

Variables, Types, and String Interpolation

Ruby is dynamically typed with no type declarations. It has local, instance, class, and global variables, differentiated by prefix symbols.

# Local variables (lowercase or underscore)
name = "Alice"
age = 30
pi = 3.14159

# String interpolation
puts "Hello, #{name}! You are #{age} years old."

# Multi-line strings (heredoc)
bio = <<~TEXT
  Name: #{name}
  Age: #{age}
  Loves Ruby!
TEXT
puts bio

# Symbols (immutable, reusable identifiers)
status = :active
direction = :north

# Conditionals
score = 85
grade = if score >= 90
  "A"
elsif score >= 75
  "B"
else
  "C"
end
puts "Grade: #{grade}"

# One-line conditional
puts "Adult" if age >= 18
puts "Retry" unless score == 100

# Case/when (Ruby's switch)
case score
when 90..100 then puts "Excellent"
when 75..89  then puts "Good"
when 60..74  then puts "Average"
else              puts "Needs improvement"
end

Loops and Iterators

Ruby has traditional loops but favors iterators with blocks. Methods like times, upto, each, and loop are idiomatic Ruby.

# times iterator
5.times { |i| puts "Iteration #{i}" }

# upto / downto
1.upto(5) { |n| print "#{n} " }
5.downto(1) { |n| print "#{n} " }

# loop with break
count = 0
loop do
  count += 1
  break if count >= 5
  puts "Count: #{count}"
end

# while
n = 1
while n <= 10
  puts n if n.odd?
  n += 1
end

# until (opposite of while)
x = 0
until x >= 3
  puts "x = #{x}"
  x += 1
end

# for..in (less common, each preferred)
for i in 1..5
  puts i
end

2. Arrays, Hashes & Ranges

Arrays and Hashes

Ruby arrays are ordered, dynamic collections. Hashes are key-value pairs, commonly using symbols as keys. Both support rich built-in methods.

# Arrays
fruits = ["apple", "banana", "mango"]
numbers = [1, 2, 3, 4, 5]

# Common array methods
fruits.push("orange")         # Add to end
fruits.unshift("grape")       # Add to front
fruits.pop                    # Remove from end
fruits.first                  # First element
fruits.last                   # Last element
fruits.length                 # Number of elements
fruits.include?("mango")      # true

# Functional methods
doubled = numbers.map { |n| n * 2 }          # [2, 4, 6, 8, 10]
evens = numbers.select { |n| n.even? }       # [2, 4]
total = numbers.reduce(0) { |sum, n| sum + n } # 15
sorted = [3, 1, 4, 1, 5].sort.uniq          # [1, 3, 4, 5]

# Hashes
person = { name: "Alice", age: 25, city: "London" }
person[:email] = "alice@example.com"          # Add key
puts person[:name]                            # Access value
person.each { |k, v| puts "#{k}: #{v}" }

# Hash methods
person.keys        # [:name, :age, :city, :email]
person.values      # ["Alice", 25, "London", ...]
person.has_key?(:age)  # true
person.merge({ country: "UK" })

# Ranges
(1..10).to_a                  # [1, 2, ..., 10] (inclusive)
(1...10).to_a                 # [1, 2, ..., 9] (exclusive)
("a".."e").to_a               # ["a", "b", "c", "d", "e"]

3. Object-Oriented Ruby

Classes and Inheritance

Everything in Ruby is an object. Classes define object blueprints. attr_accessor, attr_reader, and attr_writer generate getter/setter methods automatically.

class Animal
  attr_accessor :name, :sound
  attr_reader :legs

  def initialize(name, sound, legs)
    @name  = name   # instance variable
    @sound = sound
    @legs  = legs
  end

  def speak
    "#{@name} says #{@sound}!"
  end

  def to_s
    "#{@name} (#{@legs} legs)"
  end
end

class Dog < Animal
  def initialize(name)
    super(name, "Woof", 4)
    @tricks = []
  end

  def learn_trick(trick)
    @tricks << trick
    puts "#{@name} learned #{trick}!"
  end

  def show_tricks
    puts "#{@name} knows: #{@tricks.join(', ')}"
  end

  def speak
    super + " *wags tail*"
  end
end

dog = Dog.new("Rex")
puts dog.speak
dog.learn_trick("sit")
dog.learn_trick("shake")
dog.show_tricks
puts dog  # calls to_s

4. Blocks, Procs & Lambdas

Ruby's Functional Building Blocks

Blocks are anonymous chunks of code passed to methods. Procs and lambdas are reusable, storable blocks. They're fundamental to Ruby's functional style.

# Blocks with do..end or {}
[1, 2, 3].each do |n|
  puts n * 10
end

[1, 2, 3].each { |n| puts n * 10 }

# yield — invoke a block inside a method
def with_logging(label)
  puts "Starting: #{label}"
  result = yield   # runs the block
  puts "Done: #{label} => #{result}"
  result
end

with_logging("math") { 2 + 2 }

# Proc — stored block
square = Proc.new { |x| x ** 2 }
puts square.call(5)    # 25

double = proc { |x| x * 2 }
puts double.call(7)    # 14

# Lambda — stricter proc
multiply = lambda { |x, y| x * y }
puts multiply.call(3, 4)  # 12

# Stabby lambda syntax
greet = ->(name) { "Hello, #{name}!" }
puts greet.call("World")

# Method objects
puts [1, -2, 3, -4].map(&method(:puts))
puts [-3, -1, 2, 4].select(&:positive?)

5. Modules & Mixins

Modules as Mixins

Ruby doesn't support multiple inheritance, but modules (mixins) allow sharing methods across unrelated classes. include adds instance methods; extend adds class methods.

module Serializable
  def to_json
    vars = instance_variables.map do |var|
      key = var.to_s.delete("@")
      value = instance_variable_get(var)
      ""#{key}": "#{value}""
    end
    "{ #{vars.join(', ')} }"
  end
end

module Timestampable
  def created_at
    @created_at ||= Time.now
  end
end

class User
  include Serializable
  include Timestampable

  attr_accessor :name, :email

  def initialize(name, email)
    @name  = name
    @email = email
  end
end

class Post
  include Serializable

  attr_accessor :title, :body

  def initialize(title, body)
    @title = title
    @body  = body
  end
end

user = User.new("Alice", "alice@ruby.io")
post = Post.new("Hello Ruby", "Ruby is great!")
puts user.to_json
puts post.to_json

6. Ruby on Rails Overview

Rails MVC and ActiveRecord

Rails is a full-stack MVC web framework. ActiveRecord is its ORM — it maps classes to database tables with a rich query interface. Migrations manage schema changes.

# Model — app/models/user.rb
class User < ApplicationRecord
  has_many :posts, dependent: :destroy
  has_one :profile

  validates :name, presence: true, length: { minimum: 2 }
  validates :email, presence: true, uniqueness: true,
                    format: { with: URI::MailTo::EMAIL_REGEXP }

  scope :active, -> { where(active: true) }
  scope :admins, -> { where(role: 'admin') }

  def full_name
    "#{first_name} #{last_name}"
  end
end

# ActiveRecord queries
User.all
User.find(1)
User.find_by(email: "alice@example.com")
User.where(active: true).order(:created_at).limit(10)
User.active.admins

# Controller — app/controllers/users_controller.rb
class UsersController < ApplicationController
  def index
    @users = User.active.order(:name)
    render json: @users
  end

  def create
    @user = User.new(user_params)
    if @user.save
      render json: @user, status: :created
    else
      render json: @user.errors, status: :unprocessable_entity
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :role)
  end
end

Keep Coding with Ruby!

Ruby's elegance and expressiveness make it one of the most enjoyable languages to write. Explore Rails, Sinatra, and the rich Ruby gem ecosystem.

Happy Coding with Ruby!