Ruby attr_accessor, what is that?

Ruby attr_accessor, what is that?

The ruby attr_accessor (as the similar attr_reader and attr_writer), are helpers that define read and write methods for instance variables of a class in a clean and quick way.

The problem

Below we have a Cat class, but if we try to retrieve the name of an instantiated cat, this happens:

1
2
3
4
5
6
7
8
9
class Cat
  def initialize(name)
    @name = name
  end
end

my_cat = Cat.new("Garfield")
my_cat = my_cat.name
# => No method error

Well, of course. We need a “name” method, right?

1
2
3
4
5
6
7
8
9
class Cat
  def name
    @name
  end
end

my_cat = Cat.new("Garfield")
my_cat.name
# => "Garfield"

But what if I want to rename my cat? We could do this:

1
2
3
4
5
6
7
8
9
10
11
12
class Cat
  def name=(new_name)
    @name = new_name
  end
end

my_cat.name
# => "Garfield"

my_cat.name = "Fur Ball"
my_cat.name
# => "Fur Ball"

The ruby attr_accessor

It works, but getting it to work usually equals to only the first half of the job. Now we make it better.

Ruby has this nifty helper called attr_accessor, that can help us with this. What it does is exactly what we did in the last steps: it creates the methods for writing and reading the instance variable of our choice. If we use it the code would be like that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Cat
  attr_accessor :name

  def initialize(@name)
   @name = name
  end
end

my_cat = Cat.new("Garfield")
my_cat.name
# => "Garfield"

my_cat.name = "Fur Ball"
my_cat.name
# => "Fur Ball"

Clean and simple, isn’t it?

Other alternative is to use the helpers attr_reader and attr_writer if you just want to allow reading or writing on the variable. In the end attr_accessor is just a shorthand for:

1
2
3
4
class Cat
  `attr_reader` :name
  `attr_writer` :name
end

Bonus tips!

Don’t use more than you need

You may be tempted at first to just use attr_accessor for everything, but keep in mind that sometimes all you need is attr_reader or attr_writer.

It is generaly not a good idea to open more of your classe’s methods than you need. Remember: a smaller public API is easier to maintain.

Use the attr_reader to avoid “@”s

Since the attr_reader creates a reader method for this variable, I can just call the method instead of the variable to avoid having to type the @, like this:

1
2
3
4
5
6
7
8
9
10
11
class Dog
  attr_reader :owner

  def initialize(owner)
    @owner = owner
  end

  def owner_information
    print owner.information
  end
end

That’s all for today folks :)

Victor A.M.

Victor A.M.
Yet another passionate web developer, mostly experienced with Ruby on Rails and Vue.js.
Currently living in São Paulo and working at Plataformatec.

Vue.js Advanced: Mastering Events

In this post we will take a deep dive into the Vue.js event system, talking about the good practices, helpful tricks and common pitfalls that you will can face. Continue reading

Ruby object interfaces: Public x Private

Published on April 24, 2016

Rails transactions: The Complete Guide

Published on April 17, 2016