If you’ve been using Ruby for a while, you’ve almost certainly defined a class with one of attr_reader, attr_writer, and attr_accessor. They’re used very widely in Ruby codebases, and are in many tutorials. In this blog, we’ll breakdown this simple but powerful syntactical sugar, and see what it actually does.

attr_reader

Here’s an example class with an attr_reader. We use this when we need an attribute that should only be changed from private methods, but whose value still needs to be available publicly.

It’s used like this:

class Message
  attr_reader :user, :message
end

The example above is essentially shorthand for:

class Message
  @user = nil
  @message = nil

  def user
    return @user
  end
 
  def message
    return @message
end

attr_writer

With attr_writer, only the setter method is defined. The getter method is left out. Maybe we have a secret variable we don’t want other objects to be able to read. We want to be able to set it though.

class User
  attr_reader :name
  attr_writer :password
end

Without the syntactical sugar in the above example, you’d have to write out something like this:

class User
  @name
  @password
  
  def name
    return @name
  end

  def password=(pass)
    @password = pass
  end
end

attr_accessor

Lastly, let’s take a look at attr_accessor. It doesn’t do anything you haven’t already seen, it just creates the setter and getter methods as seen above. Let’s make use of attr_accessor for our :name variable:

class User
  attr_accessor :name
  attr_writer :password
end

Without syntactical sugar we would have to do this:

class User
  @name
  @password
  
  def name
    return @name
  end

  def name=(n_
    @name = n
  end

  def password=(pass)
    @password = pass
  end
end

Summary

So, in summary:

  • attr_* methods are syntactical sugar that create setter and getter methods
  • A setter method allows users to set the value of an instance variable on an object.
  • A getter method allows users to get the value of an instance variable from an object.
  • attr_reader creates just the getter.
  • attr_writer creates just the setter.
  • attr_accessor creates both setter and getter.