Ruby: The Language of Happiness
Learn Ruby and Rails for elegant and productive web development
1 Loading...
Ruby: The Language of Happiness
Ruby is a dynamic, open source programming language focused on simplicity and productivity. Created by Yukihiro “Matz” Matsumoto in 1995 in Japan, Ruby was designed to make programmers happy, with a natural syntax that reads almost like English.
Ruby Philosophy: “Ruby is designed to make programmers happy.” - Matz. This philosophy is reflected in every aspect of the language.
Distinctive Features
- Everything is an Object - Even numbers and booleans are objects
- Blocks and Procs - Powerful and elegant closures
- Metaprogramming - Code that writes code
- Duck Typing - If it walks like a duck and quacks…
- DSLs - Ease of creating Domain Specific Languages
- Ruby on Rails - Framework that revolutionized web development
Fundamentals
Types and Variables
# Local variables
name = "Maria"
age = 25
height = 1.68
active = true
# Symbols (immutable and unique)
status = :pending
role = :admin
# Arrays
fruits = ["apple", "banana", "orange"]
fruits << "grape" # Add
fruits.push("strawberry")
# Hashes
user = {
name: "Maria",
email: "[email protected]",
age: 25
}
# Access
user[:name] # "Maria"
user.fetch(:phone, "Not provided")
# Ranges
numbers = (1..10)
letters = ("a".."z")
numbers.to_a # [1, 2, 3, ..., 10]
# String interpolation
message = "Hello, #{name}! You are #{age} years old."
Methods and Blocks
# Simple method
def greet(name)
"Hello, #{name}!"
end
# Method with default value
def create_user(name, email, active: true)
{ name: name, email: email, active: active }
end
# Method with block
def execute_with_log
puts "Starting..."
result = yield
puts "Finishing..."
result
end
execute_with_log { 2 + 2 } # Returns 4
# Blocks with parameters
[1, 2, 3].map { |n| n * 2 } # [2, 4, 6]
# Procs and Lambdas
double = ->(x) { x * 2 }
double.call(5) # 10
# Method chaining
result = [1, 2, 3, 4, 5]
.select { |n| n.even? }
.map { |n| n * 2 }
.sum
Classes and Objects
# Basic class
class User
attr_reader :id, :email
attr_accessor :name
def initialize(name, email)
@id = SecureRandom.uuid
@name = name
@email = email
@active = true
end
def greet
"Hello, #{@name}!"
end
def active?
@active
end
def deactivate!
@active = false
end
end
# Inheritance
class Admin < User
attr_reader :permissions
def initialize(name, email, permissions = [])
super(name, email)
@permissions = permissions
end
def can?(action)
permissions.include?(action.to_sym)
end
end
# Modules (mixins)
module Timestamps
def touch
@updated_at = Time.now
end
def created_at
@created_at ||= Time.now
end
end
class Article
include Timestamps
def initialize(title)
@title = title
end
end
# Struct for simple classes
Point = Struct.new(:x, :y) do
def distance_from_origin
Math.sqrt(x**2 + y**2)
end
end
Enumerables
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Transformations
doubled = numbers.map { |n| n * 2 }
evens = numbers.select { |n| n.even? }
odds = numbers.reject { |n| n.even? }
# Reductions
sum = numbers.reduce(0) { |acc, n| acc + n }
sum = numbers.sum # Shortcut
# Searches
first_even = numbers.find { |n| n.even? }
all_even = numbers.all? { |n| n.even? }
any_even = numbers.any? { |n| n.even? }
# Grouping
groups = numbers.group_by { |n| n.even? ? :even : :odd }
# Sorting
users = [
{ name: "Maria", age: 25 },
{ name: "John", age: 30 },
{ name: "Ana", age: 22 }
]
sorted = users.sort_by { |u| u[:age] }
oldest = users.max_by { |u| u[:age] }
Metaprogramming
# Dynamic define_method
class User
[:admin, :moderator, :editor].each do |role|
define_method "#{role}?" do
@role == role
end
end
end
# method_missing for proxy
class HashWrapper
def initialize(hash)
@hash = hash
end
def method_missing(name, *args)
if @hash.key?(name)
@hash[name]
else
super
end
end
def respond_to_missing?(name, include_private = false)
@hash.key?(name) || super
end
end
wrapper = HashWrapper.new(name: "Maria", email: "[email protected]")
wrapper.name # "Maria"
Essential Ruby on Rails
# Model with validations
class User < ApplicationRecord
has_many :posts, dependent: :destroy
belongs_to :company
validates :name, presence: true, length: { minimum: 2 }
validates :email, presence: true, uniqueness: true
scope :active, -> { where(active: true) }
scope :admins, -> { where(role: :admin) }
end
# RESTful Controller
class UsersController < ApplicationController
before_action :set_user, only: [:show, :update, :destroy]
def index
@users = User.active.includes(:company)
render json: @users
end
def create
@user = User.new(user_params)
if @user.save
render json: @user, status: :created
else
render json: { errors: @user.errors }, status: :unprocessable_entity
end
end
private
def set_user
@user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:name, :email, :company_id)
end
end
Essential Tools
| Tool | Purpose |
|---|---|
| Bundler | Dependency manager |
| Rails | Full-stack web framework |
| RSpec | Testing framework |
| Rubocop | Linter and formatter |
| Pry | Advanced interactive console |
Learning Checklist
- Master blocks, procs, and lambdas
- Understand modules and mixins
- Learn Enumerable methods
- Study metaprogramming
- Practice with Ruby on Rails
- Write tests with RSpec
- Create a REST API
Essential Resources
Quote
“Ruby is simple in appearance, but very complex inside, like the human body.” - Yukihiro Matsumoto
Ruby makes programming a joyful experience. Discover the happiness of coding with Ruby!