Classes and Objects in Ruby
Defining your own classes, initializing state, and the difference between instance and class-level methods.
2 min read
Ruby was built as an object-oriented language from day one, and defining classes is where that really starts to show.
Defining a class
class Book
def initialize(title, author)
@title = title
@author = author
end
def summary
"#{@title} by #{@author}"
end
end
book = Book.new("Dune", "Frank Herbert")
puts book.summary # Dune by Frank Herbertinitialize is a special method Ruby calls automatically when you write Book.new(...) — it's the constructor. The @title and @author are instance variables: each object gets its own copy, and they're accessible from any instance method of that object without needing to be passed around.
Instance variables are private by default
book.title # NoMethodError -- there's no `title` method, only @titleInstance variables aren't accessible from outside the object at all, even without an explicit private keyword — you need a method to expose them. Writing def title; @title; end for every variable gets repetitive, which is exactly what the next lesson's attr_accessor solves.
Instance methods vs class methods
An instance method operates on one object; a class method operates on the class itself, without needing an instance:
class Book
@@count = 0
def initialize(title)
@title = title
@@count += 1
end
def self.count
@@count
end
end
Book.new("Dune")
Book.new("Neuromancer")
Book.count # 2def self.count defines a method on the class itself — called as Book.count, never book_instance.count. This is Ruby's equivalent of static methods elsewhere. @@count is a class variable, shared across every instance (used sparingly in real code — it has some sharp edges around subclassing that instance-level state doesn't).
to_s and inspect
By default, printing an object gives an unhelpful result:
puts book # #<Book:0x00007f9d3a0b8f20>Override to_s to control how an object renders as a string, which affects puts and interpolation:
class Book
def to_s
"#{@title} by #{@author}"
end
end
puts book # Dune by Frank Herbert
puts "Reading: #{book}" # Reading: Dune by Frank HerbertComparing objects
By default, == compares object identity (are these literally the same object in memory), not their contents. Override == when two objects with the same data should be considered equal:
class Book
def ==(other)
other.is_a?(Book) && @title == other.instance_variable_get(:@title)
end
end
Book.new("Dune") == Book.new("Dune") # true, with the override aboveClasses are the foundation the rest of this section builds on — modules, inheritance, and attr_accessor all extend what a plain class like Book can do.
Test what you just learned
4 quick questions. Get all of them right to unlock the next lesson.
You can take the quiz without an account — logging in just lets your result count toward your progress.