Ruby Basics

Learn Ruby programming fundamentals

Ruby Basics

Ruby is a dynamic, object-oriented programming language known for its elegant syntax and developer-friendly design. This guide covers the fundamentals you need to get started with Ruby programming.

Variables

Ruby uses different variable naming conventions to indicate scope:

# Local variables (lowercase or underscore)
name = "Ruby"
age = 30
user_name = "developer"

# Instance variables (start with @)
@name = "Instance variable"

# Class variables (start with @@)
@@count = 0

# Global variables (start with $)
$global_var = "Global"

# Constants (UPPERCASE)
PI = 3.14159
MAX_SIZE = 100

Data Types

Ruby is dynamically typed - you don't need to declare types:

# Strings
name = "Ruby"
greeting = 'Hello, World!'
interpolated = "Hello, #{name}!"

# Numbers
integer = 42
float = 3.14
big_number = 1_000_000  # Underscores for readability

# Booleans
is_active = true
is_complete = false

# Nil (Ruby's null)
value = nil

# Symbols (immutable strings)
status = :active
:user_name

Arrays

Arrays are ordered collections of objects:

# Creating arrays
fruits = ["apple", "banana", "orange"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, :symbol]

# Accessing elements
fruits[0]        # "apple" (first element)
fruits[-1]       # "orange" (last element)
fruits.first    # "apple"
fruits.last     # "orange"

# Adding elements
fruits << "grape"        # Add to end
fruits.push("mango")     # Add to end
fruits.unshift("kiwi")   # Add to beginning

# Removing elements
fruits.pop               # Remove last
fruits.shift             # Remove first
fruits.delete("banana")  # Remove specific element

# Array methods
fruits.length            # Get size
fruits.empty?            # Check if empty
fruits.include?("apple") # Check if contains
fruits.join(", ")       # Join with separator

Hashes

Hashes are key-value pairs (like dictionaries or maps):

# Creating hashes
person = {
  name: "John",
  age: 30,
  city: "New York"
}

# Or with string keys
person2 = {
  "name" => "Jane",
  "age" => 25
}

# Accessing values
person[:name]        # "John"
person["name"]       # nil (if using symbol keys)
person.fetch(:name)  # "John" (with error if missing)

# Adding/updating
person[:email] = "john@example.com"
person[:age] = 31

# Hash methods
person.keys          # [:name, :age, :city]
person.values        # ["John", 30, "New York"]
person.has_key?(:name)  # true
person.empty?        # false

Loops

Ruby offers several ways to iterate:

# Each loop (most common)
fruits = ["apple", "banana", "orange"]
fruits.each do |fruit|
  puts fruit
end

# Each with index
fruits.each_with_index do |fruit, index|
  puts "#{index}: #{fruit}"
end

# For loop
for fruit in fruits
  puts fruit
end

# While loop
count = 0
while count < 5
  puts count
  count += 1
end

# Until loop
count = 0
until count >= 5
  puts count
  count += 1
end

# Times loop
5.times do |i|
  puts "Iteration #{i}"
end

# Range iteration
(1..10).each do |num|
  puts num
end

Conditionals

Control flow with if/else statements:

# If/else
age = 20
if age >= 18
  puts "Adult"
elsif age >= 13
  puts "Teenager"
else
  puts "Child"
end

# Unless (opposite of if)
unless age < 18
  puts "Can vote"
end

# Ternary operator
status = age >= 18 ? "Adult" : "Minor"

# Case statement
grade = "B"
case grade
when "A"
  puts "Excellent"
when "B"
  puts "Good"
when "C"
  puts "Average"
else
  puts "Needs improvement"
end

# Logical operators
if age >= 18 && has_license
  puts "Can drive"
end

if is_weekend || is_holiday
  puts "Day off"
end

Methods

Methods are defined with def:

# Simple method
def greet(name)
  "Hello, #{name}!"
end

puts greet("Ruby")  # "Hello, Ruby!"

# Method with default parameters
def greet(name = "World")
  "Hello, #{name}!"
end

# Method with multiple parameters
def calculate_total(price, tax = 0.1)
  price * (1 + tax)
end

# Method returning multiple values
def get_name_and_age
  ["John", 30]
end

name, age = get_name_and_age

# Method with block
def repeat(times)
  times.times do
    yield
  end
end

repeat(3) do
  puts "Hello"
end

Classes

Ruby is object-oriented - everything is an object:

# Defining a class
class Person
  # Initialize method (constructor)
  def initialize(name, age)
    @name = name
    @age = age
  end

  # Getter methods
  def name
    @name
  end

  def age
    @age
  end

  # Setter methods
  def name=(new_name)
    @name = new_name
  end

  # Or use attr_accessor
  attr_accessor :name, :age

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

# Creating objects
person = Person.new("John", 30)
puts person.introduce
person.name = "Jane"
puts person.name

Common Patterns

# Map (transform array)
numbers = [1, 2, 3, 4]
squared = numbers.map { |n| n * n }  # [1, 4, 9, 16]

# Select (filter)
evens = numbers.select { |n| n.even? }  # [2, 4]

# Reduce (accumulate)
sum = numbers.reduce(0) { |acc, n| acc + n }  # 10

# Chaining methods
[1, 2, 3, 4, 5]
  .select { |n| n.even? }
  .map { |n| n * 2 }
  .reduce(0, :+)  # 12