Objects, modules and exceptions

Classes, attribute accessors, mixins, and the difference between include, extend and prepend.

Classes and objects

class Account
  attr_reader :owner, :balance

  def initialize(owner, opening = 0)
    @owner = owner
    @balance = opening
  end

  def deposit(amount)
    raise ArgumentError, "amount must be positive" unless amount.positive?
    @balance += amount
    self                      # return self so calls can be chained
  end

  def to_s = "#{owner}: #{balance}"    # endless method, Ruby 3.0+
end

account = Account.new("Ada", 100)
account.deposit(50).deposit(25)
puts account
  • initialize is the constructor; Account.new allocates, calls it, and returns the object regardless of what the method returns.
  • Instance variables are private by default. Expose them with attr_reader, attr_writer or attr_accessor.
  • self inside an instance method is the receiver, and is required when calling a setter: self.balance = 10.
  • Struct.new(:name, :role) and the immutable Data.define(:name, :role) generate small value classes without boilerplate.
  • Method lookup walks the singleton class, the class, included modules and then superclasses, which is why a mixed-in method can shadow a superclass one.

Modules, mixins and exceptions

module Greeting
  def greet = "Hello, #{name}"

  def self.build(name)        # module method: Greeting.build("Ada")
    "Hello, #{name}"
  end
end

class Person
  include Greeting            # instance methods
  attr_reader :name
  def initialize(name) = @name = name
end

puts Person.new("Ada").greet

module Geometry
  PI = 3.14159
  def self.area(r) = PI * r * r     # a namespace for helpers
end

begin
  raise ArgumentError, "bad input" if ARGV.empty?
rescue ArgumentError => e
  warn "caught: #{e.message}"
ensure
  puts "always runs"
end
KeywordEffect
includeAdds the module's methods as instance methods
extendAdds them to one object, or to the class itself when used in the class body
prependInserts the module before the class so it can wrap the original method
module_functionMakes a copy as a module method and a private instance method
privateNo explicit receiver, including self — a design rule, not a security boundary
⚠️
A bare rescue catches StandardError, which is usually right, but swallowing the exception silently hides bugs. Rescue the narrowest class you can handle, and always handle, re-raise, or log with context.

FAQ

Why does calling a private method with self fail?
Private methods cannot take an explicit receiver, and self counts as one. Call it with an implicit receiver, or use send in tests where you deliberately reach past the boundary.
include or extend?
include when instances need the behaviour. extend when a single object or the class itself needs it, which is the usual way to add class-level helper methods.

Syntax and blocks Standard library and a short note on Rails

Last refreshed 2026-09-18.