
Frankly, I’m sick and tired of hearing that Dr. Cham was a madman. Yes, he tried to bury himself alive. Yes, he electrocuted his niece. Yes, in fact, he did dynamite a retirement home. But this was all with good cause and, in each case, I believe he took the correct course of action.
This chapter is about classes. Classes are the blueprints Ruby uses to build objects. Once you understand classes, you understand most of what there is to know about object-oriented Ruby.
Defining a Class
class Fox
def initialize(name, age)
@name = name # @ means instance variable
@age = age
end
def speak
puts "#{@name} says: *rustle rustle*"
end
def description
"#{@name} is #{@age} years old"
end
end
trady = Fox.new("Trady Blix", 9)
trady.speak # => "Trady Blix says: *rustle rustle*"
trady.description # => "Trady Blix is 9 years old"
attr_accessor
class Fox
attr_accessor :name, :age, :color
def initialize(name, age, color = :red)
@name = name
@age = age
@color = color
end
end
f = Fox.new("Spot", 3)
f.name # => "Spot"
f.color # => :red
f.color = :silver
f.color # => :silver
attr_accessor generates both getter and setter methods for you. attr_reader generates only the getter. attr_writer only the setter. Use attr_accessor most of the time.
Inheritance
class Animal
def breathe
puts "inhale... exhale..."
end
def eat(food)
puts "nom nom nom #{food}"
end
end
class Fox < Animal
def speak
puts "*rustle*"
end
end
class Cat < Animal
def speak
puts "meow"
end
end
f = Fox.new
f.breathe # inherited from Animal: "inhale... exhale..."
f.speak # own method: "*rustle*"
f.eat("chunky bacon") # inherited: "nom nom nom chunky bacon"
Modules
module Greetable
def greet
"Hello! I am #{name}"
end
end
module Trackable
def log_action(action)
puts "[#{self.class}] #{action} at #{Time.now}"
end
end
class Person
include Greetable
include Trackable
attr_reader :name
def initialize(name)
@name = name
end
end
p = Person.new("Trady Blix")
p.greet # => "Hello! I am Trady Blix"
p.log_action("spoke") # => "[Person] spoke at 2026-..."
Modules allow you to share behavior across classes that don’t share a parent class. They are Ruby’s answer to multiple inheritance. A class can include as many modules as needed.
Class Methods vs Instance Methods
class TextSample
@@count = 0 # class variable
def initialize(text)
@text = text
@@count += 1
end
def word_count
@text.split.length
end
def self.total_created
@@count
end
end
t1 = TextSample.new("chunky bacon is chunky")
t2 = TextSample.new("why the lucky stiff")
t1.word_count # => 4 (instance method)
TextSample.total_created # => 2 (class method)