What does attr_accessor do in Ruby?

Ruby 2 min read
Short answer

attr_accessor :name defines both name and name= methods. attr_reader defines only the getter, attr_writer only the setter.

ruby
class Video
  attr_accessor :title
  attr_reader :views          # read-only from outside

  def initialize(title)
    @title = title
    @views = 0
  end
end

That is equivalent to writing:

ruby
def title
  @title
end

def title=(value)
  @title = value
end

#Instance variables are private

@title is only reachable from inside the object. Without an accessor there is no way to read it from outside — which is the point. You expose exactly what should be exposed.

attr_reader is the right default. Add attr_accessor only when outside code genuinely needs to change the value.

#Use the reader inside the class too

ruby
def summary
  "#{title} — #{views} views"      # prefer this
  "#{@title} — #{@views} views"    # over this
end

Going through the method means that if you later add logic — lazy loading, formatting, a default — every caller including the class itself picks it up.

#Assigning inside the class needs self

ruby
def reset
  self.title = "Untitled"     # calls the setter
  title = "Untitled"          # creates a LOCAL VARIABLE — does nothing
end

This one catches everyone. Without self., Ruby cannot tell a setter call from a local assignment, and it chooses the local.

#Multiple at once

ruby
attr_accessor :title, :track, :duration

#Structs, when that is all the class does

ruby
Video = Struct.new(:title, :views, keyword_init: true)
Video.new(title: "Intro", views: 197)

Or Data.define(:title, :views) in Ruby 3.2+ for an immutable value object.