Ruby - How to use attr_accessor, attr_writer, and attr_reader
Introduction
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 by re-implementing them in pure Ruby.
attr_reader
How to use it
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
message.user
# => michael.rodrigues
How it works
The example above is essentially shorthand for the following. We manually define two getters: one for user
and one for message
:
class Message
@user = nil
@message = nil
def user
return @user
end
def message
return @message
end
end
attr_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:
class User
attr_reader :name
attr_writer :password
end
michael.password = "secretpassword"
How it works
Without the syntactical sugar in the above example, you’d again have to manually define a getter and a setter:
class User
@name
@password
def name
return @name
end
def password=(pass)
@password = pass
end
end
attr_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 make use of attr_accessor
for our :name
variable:
class User
attr_accessor :name
attr_writer :password
end
michael.name
# => Mike
michael.name = "Michael"
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:
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.
Don’t be shy with the sugar!