What is attr_accessor in Ruby?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
attr_accessor is a Ruby class macro that automatically creates both a reader method and a writer method for an instance variable. It saves you from writing simple getter and setter methods by hand. The feature is small, but it is central to how Ruby classes expose state cleanly.
What attr_accessor Generates
When you write attr_accessor :title, Ruby defines two instance methods for the class:
- '
title' - '
title='
That means this class:
behaves roughly like this manual version:
The macro does not create the instance variable itself. The variable still needs to be assigned somewhere, usually in initialize.
Compare It with attr_reader and attr_writer
Ruby gives you three common attribute macros:
- '
attr_readerfor read-only accessors' - '
attr_writerfor write-only accessors' - '
attr_accessorfor both'
Choosing between them is about interface design, not convenience alone. If external code should not modify a field directly, attr_reader is often a better fit than attr_accessor.
It Helps, but It Is Not a Replacement for Encapsulation
A common beginner mistake is to add attr_accessor for every instance variable without thinking about object design. That makes internal state widely mutable, which can weaken invariants.
For example, a BankAccount class might not want arbitrary code to set balance directly.
Here, attr_reader is the better choice because writes should go through validated behavior. attr_accessor would be too permissive.
You Can Still Override the Generated Methods
attr_accessor is not a trap. You can start with it and later replace either generated method with custom logic.
Ruby keeps the reader from attr_accessor, while your custom writer overrides the generated one. This is one reason the macro works well in evolving codebases.
It Is Just a Method Call in the Class Body
Another useful mental model is that attr_accessor is simply a method being executed while the class is defined.
That is why it can accept multiple symbols at once, and why Ruby metaprogramming libraries can build on the same idea. Understanding this makes Ruby class definitions feel less magical.
Use It for the Public Interface You Actually Want
The right question is not "Should I save typing?" The right question is "Should outside code be able to read this, write this, both, or neither?" attr_accessor is excellent when both are appropriate. When they are not, use the more restrictive macro or define custom methods.
That mindset keeps Ruby classes expressive instead of accidentally turning them into bags of mutable fields.
Common Pitfalls
- Assuming
attr_accessorcreates and initializes the instance variable automatically. - Using
attr_accessorfor every field without considering encapsulation. - Forgetting that
attr_writercreates only a setter and no reader. - Exposing state that should really be changed through validated domain methods.
- Treating the macro as magic instead of understanding that it defines ordinary Ruby methods.
Summary
- '
attr_accessorcreates both a getter and a setter for an instance variable.' - It reduces boilerplate, but it should still reflect the intended public interface.
- Use
attr_readerorattr_writerwhen only one direction of access is appropriate. - Generated methods can be overridden later with custom logic.
- Good Ruby design uses these macros to support encapsulation, not bypass it.

