attr_accessor and Friends
Fast recall
Quick revision
Core answer
attr_reader :name defines a getter method, attr_writer :name defines a setter named name=, and attr_accessor :name defines both for the instance variable @name. They are method-generating conveniences, not special public fields. Use the narrowest access needed so important state changes can still pass through validation.Whether you know attr_reader (getter), attr_writer (setter), attr_accessor (both), and that they generate methods from instance variables.
Over-exposing with attr_accessor when attr_reader would do (don't expose setters you don't need).
attr_accessor = getter + setter; attr_reader = getter only; attr_writer = setter only. Generate methods from @vars. Prefer attr_reader by default.
Interview-ready guide
Interview answer
Ruby's attribute helpers generate ordinary instance methods. attr_reader :name creates a getter named name, attr_writer :name creates a setter named name=, and attr_accessor :name creates both. They remove repetitive method definitions; they do not create a special kind of public field.
user.name = "Ada" still calls the method name=("Ada"), even though it looks like direct field assignment. The generated getter usually returns @name, and the setter stores a value in @name. Because they are normal methods, accessors can be inherited, overridden, or made private.
A nickname may safely use attr_accessor, but a bank balance should not allow arbitrary replacement. The Account below exposes balance for reading and changes it through deposit, where the object can reject an invalid amount and preserve its rules.
Use attr_reader as a safe default and add a writer only when any replacement value is valid. Write a custom setter or a domain method when a change needs validation, normalisation, logging, or another business rule. Also initialise required state deliberately: reading an instance variable that was never assigned returns nil.
attr_accessor and Friends
Direct Answer
attr_reader :name defines a getter method, attr_writer :name defines a setter named name=, and attr_accessor :name defines both for the instance variable @name. They are method-generating conveniences, not special public fields. Use the narrowest access needed so important state changes can still pass through validation.
Deep Dive & Architecture
Ruby does not have a separate public-field mechanism behind these helpers. attr_reader, attr_writer, and attr_accessor are methods on Module that define instance methods in the class currently being built. The generated getter and setter participate in inheritance, visibility, overriding, and reflection like methods written with def.
Setter syntax has one special visual rule: account.balance = 10 still sends the message balance= with 10. A custom setter can normalise or reject the value, but relying on side effects inside assignment can be surprising because Ruby assignment expressions return the right-hand value.
A reader is useful even when direct writing is unsafe. It lets callers observe state while the object remains responsible for transitions. withdraw(amount) can check that the amount is positive and affordable, then update @balance once. A raw balance writer would let every caller bypass those conditions.
Accessors can be inherited or overridden. If a subclass needs a different representation, it may redefine the method without changing callers. That is another reason to think of name as a public message rather than a promise that an instance variable with the same spelling will always exist.
Code Example
class Account
attr_reader :balance
def initialize(balance = 0)
@balance = balance
end
def deposit(amount)
raise ArgumentError, 'amount must be positive' unless amount.positive?
@balance += amount
end
end
account = Account.new(100)
account.balance # => 100
account.deposit(25) # => 125
account.balance # => 125
# account.balance = -1 # NoMethodError: no public writer
Common Mistakes & Pitfalls
Over-exposing with attr_accessor when attr_reader would do (don't expose setters you don't need).
Check your understanding
Answer these without looking back at the article.
- When would you use Attr Accessor in a real project?
- How would you compare Attr Accessor with an alternative?
- What is a common mistake when using Attr Accessor?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.