Question

What attr_accessor Means in Ruby: Getters and Setters Explained

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 getter
  • attr_writer :name → creates only the setter
  • attr_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 @name is 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.

Take Quiz

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 :name created name and name= methods.
  • person.name = "Alice" calls the setter method.
  • person.name calls 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:

  • color
  • color=

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, or role
  • 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, or position

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.

Take Quiz

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_accessor for simple, public attributes.
  • Use attr_reader if 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

HelperCreates getter?Creates setter?Typical use
attr_readerYesNoRead-only attribute
attr_writerNoYesWrite-only attribute
attr_accessorYesYesReadable and writable attribute

Manual methods vs attr_accessor

ApproachProsCons
Manual getter/setter methodsFull controlMore code
attr_accessorShort and clearLess explicit if you need custom logic later

When to choose each

  • Choose attr_reader when outside code should only read the value.
  • Choose attr_writer when outside code should only set the value.
  • Choose attr_accessor when both actions make sense.
  • Choose manual methods when you need validation, formatting, logging, or other behavior.
Take Quiz

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 = value inside 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.

Take Quiz

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 BankAccount class.
  • 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 deposit and withdraw methods to change the balance.
  • Prevent withdrawing more money than the current balance.
Take Quiz

Keep learning

Related questions

View more