Question
I am having trouble understanding attr_accessor in Ruby. What does it do, and how is it used in a class? Could someone explain it clearly with examples?
Short Answer
By the end of this page, you will understand what attr_accessor does in Ruby, why it is useful, and how it automatically creates getter and setter methods for instance variables. You will also see how it compares with attr_reader and attr_writer, how it works in real classes, and which beginner mistakes to avoid.
Concept
In Ruby, attr_accessor is a shortcut for creating two instance methods for an object:
- a getter method, which lets you read a value
- a setter method, which lets you change a value
It is usually used for instance variables such as @name, @age, or @price.
Without attr_accessor, you would need to write these methods yourself.
class Person
def name
@name
end
def name=(value)
@name = value
end
end
Ruby lets you replace both methods with this:
class Person
attr_accessor :name
end
That line creates the same two methods automatically.
Why this matters
In object-oriented programming, classes often hold data inside instance variables. But code outside the object should usually interact with that data through methods, not by directly accessing internal variables.
attr_accessor makes that common pattern much easier.
What it creates
If you write:
attr_accessor :name
Ruby creates methods like these:
def name
@name
end
def name=(value)
@name = value
end
Related shortcuts
Ruby provides three common attribute helpers:
attr_reader :name→ creates only the getterattr_writer :name→ creates only the setterattr_accessor :name→ creates both getter and setter
Use attr_accessor when the value should be both readable and writable.
Mental Model
Think of an object as a small machine with labeled controls.
- The instance variable like
@nameis a value stored inside the machine. - A getter is like a display screen that lets you read the value.
- A setter is like a button or dial that lets you change the value.
attr_accessor tells Ruby:
"Please add both the display screen and the control dial for this piece of data."
So instead of building both parts manually every time, Ruby builds them for you.
If you only want people to see the value, use attr_reader.
If you only want them to change it, use attr_writer.
If you want both, use attr_accessor.
Syntax and Examples
Basic syntax
class ClassName
attr_accessor :attribute_name
end
You can define multiple attributes at once:
class Person
attr_accessor :name, :age
end
Simple example
class Person
attr_accessor :name
end
person = Person.new
person.name = "Alice"
puts person.name
Output:
Alice
What happened?
attr_accessor :namecreatednameandname=methods.person.name = "Alice"calls the setter method.person.namecalls the getter method.
Equivalent manual version
class Person
def name
@name
end
def name=(value)
@name = value
end
end
This behaves the same way as using attr_accessor.
Example with initialize
class Book
attr_accessor :title, :author
def initialize(title, author)
@title = title
@author = author
end
end
book = Book.new("1984", "George Orwell")
puts book.title
book.title = "Animal Farm"
puts book.title
This is very common in Ruby classes: set starting values in initialize, then access them through generated methods.
Step by Step Execution
Example
class Car
attr_accessor :color
def initialize(color)
@color = color
end
end
car = Car.new("red")
puts car.color
car.color = "blue"
puts car.color
Step by step
1. Ruby reads the class definition
attr_accessor :color
Ruby creates two methods:
colorcolor=
2. A new object is created
car = Car.new("red")
Ruby calls initialize("red").
3. The instance variable is set
@color = color
Inside this object, @color becomes "red".
4. The getter is called
puts car.color
Ruby calls the generated color method, which returns @color.
Output:
red
5. The setter is called
car.color = "blue"
Ruby calls the generated color= method with "blue".
That method updates @color.
6. The getter is called again
puts car.color
Now it returns "blue".
Output:
blue
Real World Use Cases
attr_accessor is used whenever a Ruby object needs simple readable and writable properties.
Common examples
- User models with values like
name,email, orrole - Configuration objects that store options
- Form objects that collect input values
- Plain Ruby objects used for service classes or data transfer
- Game objects with properties like
health,speed, orposition
Example: configuration object
class AppConfig
attr_accessor :host, :port
def initialize
@host = "localhost"
@port = 3000
end
end
config = AppConfig.new
config.port = 4000
puts "#{config.host}:#{config.port}"
Example: simple domain object
class Product
attr_accessor :name, :price
def initialize(name, price)
@name = name
@price = price
end
end
These kinds of classes appear often in scripts, libraries, and web applications.
Real Codebase Usage
In real projects, developers use attr_accessor for attributes that are safe to read and change directly.
Common patterns
Simple data objects
class Result
attr_accessor :success, :message
def initialize(success, message)
@success = success
@message = message
end
end
Prefer attr_reader when writing should be restricted
In many codebases, developers avoid making everything writable.
class User
attr_reader :id, :email
def initialize(id, email)
@id = id
@email = email
end
end
This prevents accidental changes like user.id = 99.
Custom setter for validation
Sometimes developers start with attr_accessor, then replace the setter when they need rules.
class Product
attr_reader :price
def price=(value)
raise ArgumentError, "Price must be non-negative" if value < 0
@price = value
end
end
Using generated methods inside the class
A class can call its own getter and setter methods too.
class Counter
attr_accessor :count
def initialize
@count = 0
end
def increment
self.count = count + 1
end
end
Notice self.count = is needed for the setter. Without self, Ruby may think you are creating a local variable.
Practical advice
- Use
attr_accessorfor simple, public attributes. - Use
attr_readerif outside code should only read. - Write custom methods if setting a value needs validation or side effects.
Common Mistakes
1. Thinking attr_accessor creates the variable itself
attr_accessor creates methods, not the initial value.
class Person
attr_accessor :name
end
person = Person.new
p person.name
This returns nil because @name has not been assigned yet.
Fix
Set a value in initialize or later with the setter.
class Person
attr_accessor :name
def initialize
@name = "Unknown"
end
end
2. Forgetting self when calling a setter inside the class
Broken example:
class Counter
attr_accessor :count
def increment
count = count + 1
end
end
This does not call the setter correctly.
Fix
class Counter
attr_accessor :count
def increment
self.count = count + 1
end
end
3. Using attr_accessor when an attribute should not be writable
Beginners often make every field writable.
class User
attr_accessor :id
end
This allows code to change id, which may be unsafe.
Better
class User
attr_reader :id
end
4. Confusing local variables with instance variables
This is wrong if you expect the value to be stored on the object:
class Person
def initialize(name)
name = name
end
end
Fix
class Person
def initialize(name)
@name = name
end
end
Or with a setter:
class Person
attr_accessor :name
def initialize(name)
self.name = name
end
end
Comparisons
Attribute helpers in Ruby
| Helper | Creates getter? | Creates setter? | Typical use |
|---|---|---|---|
attr_reader | Yes | No | Read-only attribute |
attr_writer | No | Yes | Write-only attribute |
attr_accessor | Yes | Yes | Readable and writable attribute |
Manual methods vs attr_accessor
| Approach | Pros | Cons |
|---|---|---|
| Manual getter/setter methods | Full control | More code |
attr_accessor | Short and clear | Less explicit if you need custom logic later |
When to choose each
- Choose
attr_readerwhen outside code should only read the value. - Choose
attr_writerwhen outside code should only set the value. - Choose
attr_accessorwhen both actions make sense. - Choose manual methods when you need validation, formatting, logging, or other behavior.
Cheat Sheet
# Read only
attr_reader :name
# Write only
attr_writer :name
# Read and write
attr_accessor :name
# Multiple attributes
attr_accessor :name, :age, :email
What attr_accessor :name creates
def name
@name
end
def name=(value)
@name = value
end
Key rules
- Works with instance variables like
@name - Creates methods, not initial values
- Use
self.name = valueinside the class when calling the setter - Reading an unset instance variable returns
nil
Quick example
class Person
attr_accessor :name
end
p = Person.new
p.name = "Alice"
puts p.name
Good default choices
- Need read only?
attr_reader - Need read and write?
attr_accessor - Need validation? Write a custom setter
FAQ
What does attr_accessor do in Ruby?
It creates both a getter and a setter method for an instance variable.
Is attr_accessor the same as an instance variable?
No. @name is the instance variable. attr_accessor :name creates methods that read and write that variable.
What is the difference between attr_accessor and attr_reader?
attr_reader creates only a getter. attr_accessor creates both getter and setter methods.
Do I always need attr_accessor in a Ruby class?
No. Use it only when an attribute should be publicly readable and writable.
Why does person.name = "Alice" work?
Because attr_accessor :name creates a setter method called name=.
Why do I need self for setters inside a class?
Without self, Ruby may interpret name = value as a local variable assignment instead of a method call.
Does attr_accessor set a default value?
No. It only creates methods. You still need to assign a value yourself.
Mini Project
Description
Build a small Ruby class that represents a bank account. This project shows how attr_accessor, attr_reader, and regular methods work together in a practical object. It demonstrates storing object state, reading values, updating values, and protecting data that should not be changed freely.
Goal
Create a BankAccount class that lets you read account information, update the owner's name, and deposit or withdraw money safely.
Requirements
- Create a
BankAccountclass. - Allow the account owner's name to be both readable and writable.
- Allow the balance to be readable, but not directly writable from outside the class.
- Add
depositandwithdrawmethods to change the balance. - Prevent withdrawing more money than the current balance.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.