Ruby: OOP, Modules & Mixins
Classes
class Animal
attr_accessor :name, :age # generates getter + setter
attr_reader :species # getter only
attr_writer :nickname # setter only
@@count = 0 # class variable
def initialize(name, age, species)
@name = name
@age = age
@species = species
@@count += 1
end
def self.count # class method
@@count
end
def to_s # string representation
"#{@species} named #{@name}"
end
def <=>(other) # comparison (enables sort)
@age <=> other.age
end
protected
def secret_method # only accessible within class hierarchy
end
private
def internal # only accessible within this object
end
end
class Dog < Animal # inheritance
def initialize(name, age)
super(name, age, "Dog") # call parent initialize
end
def speak
"Woof!"
end
def to_s
super + " (dog)" # call parent to_s
end
end
rex = Dog.new("Rex", 3)
puts rex # "Dog named Rex (dog)"
Dog.count # 1Modules & Mixins
# Module: namespace + mixin (can't be instantiated)
module Greetable
def greet
"Hello, I am #{name}"
end
def farewell
"Goodbye from #{name}"
end
end
module Serializable
def to_json
instance_variables.each_with_object({}) do |var, h|
h[var.to_s.delete('@')] = instance_variable_get(var)
end.to_json
end
end
class Person
include Greetable # mixin — adds instance methods
include Serializable
extend Greetable # extend — adds as class methods
attr_reader :name
def initialize(name)
@name = name
end
end
alice = Person.new("Alice")
alice.greet # "Hello, I am Alice"
alice.to_json # '{"name":"Alice"}'
# Comparable mixin — adds <, <=, >, >=, between?, clamp
class Box
include Comparable
attr_reader :volume
def initialize(volume)
@volume = volume
end
def <=>(other)
volume <=> other.volume
end
end
# Enumerable mixin — adds map, select, sort, etc.
class WordCollection
include Enumerable
def initialize(words)
@words = words
end
def each(&block) # Enumerable requires each
@words.each(&block)
end
endDuck Typing & Interfaces
Ruby has no interfaces — uses duck typing: "if it responds to the method, it works"
respond_to?(:method_name) — check before calling a method on an unknown object
is_a? / kind_of? — check class membership
Comparable, Enumerable — standard mixins that define protocols through duck typing
Struct: Struct.new(:name, :age) — creates a simple class with accessors and equality
Point = Struct.new(:x, :y) do
def distance_to(other)
Math.sqrt((x - other.x)**2 + (y - other.y)**2)
end
end
p = Point.new(0, 0)
q = Point.new(3, 4)
p.distance_to(q) # 5.0
p == Point.new(0, 0) # true (value equality)Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free