Ruby - attr_accessor, attr_writer, and attr_reader
Introduction
If you’ve been using Ruby for a while, you’ve almost certainly seen a class defined with one of the methods in the article title. They’re used very widely in Ruby codebases and tutorials. In this blog, we’ll breakdown this simple but powerful syntactical sugar, and see what it actually does by re-implementing them in pure Ruby.
Why use them?
In case you’re brand new to them, let’s take a quick minute to see why you would actually want to use these.
If you’re defining a class
in Ruby, you’ve probably got some attributes that you want to store on the class, and access. Let’s look at a super simple User
class:
We just want to store a name
var on the User
object we created. We can do that, but we can’t access that name without getting an error. Let’s try something else:
OK, so that worked, but it’s absolutely ugly and tedious. Who wants to type that out every time? No one. This is where getters
and setters
come in. Remember that first error?
It’s telling us exactly what we need to do.
We need to define our name
method before we call it. Let’s take another stab at writing our User
class, but let’s define that accessor method:
Boom! it works, all we had to do was define a simple getter method. Anyways, this method is super simple, and you may have a bunch of attributes on a single class. Also consider that you may want to create a setter method, so you can do something like change the name
variable after creating the object:
You will get another NoMethodError
if you haven’t defined the setter, but ou can avoid writing the method by just using attr_writer
or attr_accessor
. Anyways, now that you know what it’s for, let’s dig a little deeper into how each one works:
Reader
How to use it
Here’s an example class with an attr_reader
. We use this when we need an variable that should only be changed from private methods, but whose value still needs to be available publicly.
It’s used like this:
How it works
The example above is essentially shorthand for the following. We manually define two getters: one for user
and one for message
:
Writer
How to use it
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:
How it works
Without the syntactical sugar in the above example, you’d again have to manually define a getter and a setter:
Accessor
How to use it
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 use it for our :name
variable:
How it works
This example really gives you an idea of how this syntactical sugar sweetens the experience. Without it, we would have to do this:
Summary
So, in summary:
- These 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.
Don’t be shy with the sugar!