Classes and Objects in Ruby
Classes and objects are the foundation of object-oriented programming in Ruby. If you’ve been learning Ruby, you’ve already been using objects—strings, arrays, and hashes are all objects. Now it’s time to create your own.
In this tutorial, you’ll learn what classes are, how to define them, and how to use objects to organize your code.
What Are Classes and Objects?
A class is a blueprint for creating objects. It defines what attributes and behaviors objects of that type will have. An object is a specific instance of a class—it’s created from the blueprint and has its own unique data.
Think of it like a cookie cutter and cookies:
- The class is the cookie cutter (the blueprint)
- Each cookie is an object (an instance)
In Ruby, everything is an object. Even numbers and nil are objects with their own classes (Integer and NilClass).
Defining a Class
To create a class in Ruby, use the class keyword followed by the class name in CamelCase:
class Person
# This is where we'll define the class behavior
end
Class names must start with a capital letter. By convention, multi-word class names use CamelCase like BankAccount or ShoppingCart.
Creating Objects
Once you have a class, you can create objects (instances) using the .new method:
class Person
end
person1 = Person.new
person2 = Person.new
puts person1.class # => Person
puts person2.class # => Person
Each call to Person.new creates a new, separate object.
The initialize Method
The initialize method is a special method that runs automatically when you call .new. It’s Ruby’**s equivalent of a constructor:
class Person
def initialize
puts "A new person is born!"
end
end
person = Person.new
# Output: A new person is born!
You’ll typically use initialize to set up the object’s initial state with instance variables.
Instance Variables
Instance variables store data that belongs to each individual object. They start with @ and are accessible throughout the class:
class Person
def initialize(name, age)
@name = name
@age = age
end
end
person1 = Person.new("Alice", 30)
person2 = Person.new("Bob", 25)
# Each object has its own @name and @age
Instance variables are private by default—you can’t access them directly from outside the object.
Instance Methods
Instance methods are behaviors that belong to objects. They’re defined inside the class and can access instance variables:
class Person
def initialize(name, age)
@name = name
@age = age
end
def greet
"Hello, my name is #{@name}!"
end
def celebrate_birthday
@age += 1
"Happy birthday! I am now #{@age} years old."
end
end
person = Person.new("Alice", 30)
puts person.greet # => Hello, my name is Alice!
puts person.celebrate_birthday # => Happy birthday! I am now 31 years old.
Accessor Methods
To read or modify instance variables from outside the object, you need accessor methods. Ruby provides shorthand macros for this:
class Person
def initialize(name, age)
@name = name
@age = age
end
# Shorthand for reading the variable
attr_reader :name
# Shorthand for modifying the variable
attr_writer :name
# Shorthand for both reading and writing
attr_accessor :age
end
person = Person.new("Alice", 30)
# Using attr_reader
puts person.name # => Alice
# Using attr_writer
person.name = "Alicia"
puts person.name # => Alicia
# Using attr_accessor
puts person.age # => 30
person.age = 31
puts person.age # => 31
For most cases, use attr_accessor to create both getter and setter methods. Use attr_reader or attr_writer when you only need one.
The to_s Method
Ruby calls the to_s method automatically when you convert an object to a string (like with puts). Override it to make your objects display useful information:
class Person
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
end
def to_s
"Person: #{@name}, #{@age} years old"
end
end
person = Person.new("Alice", 30)
puts person
# => Person: Alice, 30 years old
Class Variables and Class Methods
Sometimes you need data that belongs to the class itself, not individual objects. Use class variables (@@) and class methods:
class Person
# Class variable - shared by all instances
@@population = 0
def initialize(name)
@name = name
@@population += 1 # Increment when new person created
end
# Class method - called on the class, not instances
def self.population
@@population
end
def introduce
"Hi, I'm #{@name}"
end
end
person1 = Person.new("Alice")
person2 = Person.new("Bob")
puts Person.population # => 2
puts person1.introduce # => Hi, I'm Alice
Class methods are defined with self.method_name and are useful for factory methods or operations that don’t need instance data.
When to Use Classes
Use classes when you need to:
- Model real-world entities with properties and behaviors
- Group related data and functionality together
- Create multiple instances with shared behavior but different data
- Organize code into reusable components
When Not to Use Classes
Avoid classes when:
- You only need to group a few unrelated methods
- A simple module would suffice
- Functional programming patterns fit better (like with
Enumerable)
Conclusion
Classes and objects are essential tools in Ruby. They let you create custom data types with their own behavior, organize code logically, and model real-world concepts in your programs.
Key takeaways:
- A class is a blueprint; an object is an instance of that class
- Use
initializeto set up new objects - Instance variables (
@) store per-object data attr_accessor,attr_reader, andattr_writercreate getter/setter methods- Class variables and methods belong to the class itself
Next Steps
Now that you understand classes and objects, continue with:
- Modules and Mixins — Reuse code across classes
- Inheritance and Method Lookup — Build on existing classes