Skip to content
AgileLogics
5 min read

Encapsulation: public, private, and protected

Prerequisites: Inheritance

Encapsulation means hiding an object's internal details and only exposing what other code needs. It lets you change the internals later without breaking code that uses the object.

Real-world analogy: a coffee machine has one button on the outside and a lot of plumbing inside. You press the button; you don't reach into the boiler.

Ruby controls this with three levels of method visibility:

Visibility Who can call it
public Anyone (the default)
private Only the object itself, without an explicit receiver
protected The object and other objects of the same class family

Example

class PasswordChecker
  MIN_LENGTH = 8

  def strong?(password)
    long_enough?(password) && mixed?(password)
  end

  private

  def long_enough?(password)
    password.length >= MIN_LENGTH
  end

  def mixed?(password)
    password.match?(/\d/) && password.match?(/[A-Za-z]/)
  end
end

checker = PasswordChecker.new
p checker.strong?("abc12345")
p checker.strong?("password")
checker.long_enough?("x")

Expected output

true
false
checker.rb:22:in '<main>': private method 'long_enough?' called for an instance of PasswordChecker (NoMethodError)

checker.long_enough?("x")
       ^^^^^^^^^^^^^

Every method below the private keyword is private. The public strong? method is the object's interface; the helpers can be renamed or rewritten freely because no outside code can depend on them.

protected

protected is useful when objects of the same class need to compare internal data without exposing it to everyone:

class Account
  def initialize(balance)
    @balance = balance
  end

  def richer_than?(other)
    balance > other.balance
  end

  protected

  attr_reader :balance
end

p Account.new(100).richer_than?(Account.new(50))
true

Visibility in Ruby is a strong convention rather than a locked door — send can call private methods (Level 3 covers why that exists). Treat private as "not part of the public interface; don't depend on it".

Common mistakes

  • Making everything public "just in case". Every public method is a promise other code may rely on; keep the list short.