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.