In this section, we will learn what attribute accessor methods are and how to use them in Ruby.
Note: we’re assuming you’re already familiar with the Ruby instance variables.
What is Attribute Accessor Method in Ruby?
In the Instance Variables section, we mentioned they are private to the outside world and the only way of accessing them is by using instance methods!
This means if you want to set a value for an instance variable, you’ll need a setter method (a method that takes a new value and assign that to the target instance variable) and of course if you want to take the value of an instance variable, you’ll need a getter method (a method that its purpose is to return the current value of the target instance variable).
Now if our setter and getter methods are just there to only set and return value of an instance variable (without ever changing the value we set or get from the instance variable) it might be tedious to create two methods for each instance variable then! (Especially if there are a couple of instance variables and we want to have getter and setter methods for all of them).
Now Ruby has provided a shorter version of creating setter and getter methods, for instance variables that is called Attribute Accessor!
The attribute-accessor allows us to create an instance variable as well as its setter and getter methods in just one single line of statement.
Alright, now that we know what they are, let’s see their types and how to use them in a program.
Types of Attribute Accessors in Ruby:
The Ruby Attribute Accessor has three types and based on which one of these types we use in our program, we either get only a setter method for an instance variable (hence the variable becomes writable only), or only a getter method (hence the variable becomes read-only) or both of the methods (hence the variable becomes readable and writable):
– attr_accessor
– attr_reader
– attr_writer
Note: when using an attribute accessor to create an instance variable, the declaration should be in the body of the class and outside of any instance method.
Ruby Attribute Accessor: attr_accessor
Using the attr_accessor we can create an instance variable in a single line of statement that has both getter and setter methods as well.
Ruby attr_accessor Syntax:
attr_accessor :instance_variable_name
Here we first started with the keyword `attr_accessor` and then followed by that an empty space and then comes the name of the instance variable that we want to create in our program.
Note: the name of an instance variable in this case will be prefixed with a colon `:`.
Also, you can create multiple instance variables in the same line using the attr_accessor!
For example:
attr_accessor :variable_one, :variable_two, :variable_n
Example: usign attr_accessor in Ruby
class Person attr_accessor :first_name attr_accessor :last_name attr_accessor :id end prs = Person.new prs.first_name = "John" prs.last_name = "Doe" prs.id = 43 puts prs.first_name, prs.last_name, prs.id
Output:
John Doe 43
Here’s what happened in this example:
We’ve called the Attribute Accessor attr_accessor three times and this is what we’ve got behind the scene:
Three instance variable is now created with the names:
- @first_name - @last_name - @id
Three setter methods are now created:
- first_name= (newValue) - last_name= (newValue) - id= (newValue)
Note: as mentioned in the method section, the name of a method can contain symbols like ?, !, and = as well. So if you see the = sign at the end of the name of a method, there’s nothing special happening here! It’s just the name of the method that has this symbol in it as well.
The body of these setter methods is designed to set the value of the `newValue` parameter as the new value of their relative instance variables.
Also, using the `attr_accessor` we got three getter methods as well:
- first_name () - last_name () - id()
The body of these getter methods is designed to return the current value of their relative instance variables to the caller.
As you can see, in this example, we just called the attr_accessor three times to create three instance variable but then Ruby automatically (and behind the scene) has created all the actual instance variables, getter and setter methods for us.
So remember that the attribute accessor is just syntax sugar for automatically creating all the necessary setter and getter methods we need for an instance variable.
In short, if we take back and look behind the scene to see what we got by calling the attr_accessor, this would be the result:
class Person def first_name= (newValue) @first_name = newValue end def last_name= (newValue) @last_name = newValue end def id= (newValue) @id = newValue end def first_name return @first_name end def last_name return @last_name end def id return @id end end prs = Person.new prs.first_name = "John" prs.last_name = "Doe" prs.id = 43 puts prs.first_name, prs.last_name, prs.id
Output:
John Doe 43
Ruby Setter Method Note:
When using `=` sign at the end of a method name, Ruby will treat that method specially! Basically you can call such setter method with space between the `=` sign and the name of the method just like the way we did in the examples above.
But you’re still capable of calling the method the same way you did when calling other methods!
For example:
prs.first_name=("John") prs.last_name=("Doe") prs.id=(43)
Ruby Attribute Accessor: attr_reader
The attr_reader is a way of creating instance variables that are read-only!
Basically, using the `attr_reader` you’ll get the getter methods automatically created for you but you won’t get the setter methods anymore!
Now, if you want to have the setter methods as well, you need to create them manually for yourself.
The use of `attr_reader` is especially useful when we just want to return the value of an instance variable without any modification! So using it will automatically create the necessary getter methods.
Now we are free to create our own setter methods with any necessary checkpoints in the body of the methods.
Ruby attr_reader Syntax:
attr_reader :variable_name
Example: using attr_reader in Ruby
class Person attr_reader :first_name, :last_name, :id def first_name= (newValue) if newValue == "unknown" puts "You can't use the value unknown as the value for the first name" else @first_name = newValue end end def last_name= (newValue) if newValue == "unknown" puts "You can't use the value unknown as the value for the last name" else @last_name = newValue end end def id= (newValue) if newValue == 0 puts "You can't use the value 0 as the value for the id " else @id = newValue end end end prs = Person.new prs.first_name = "John" prs.last_name = "unknown" prs.id = 43 puts prs.first_name, prs.last_name, prs.id
Output:
You can't use the value unknown as the value for the last name John 43
As you can see, using the attr_reader we got the instance variables and their getter methods as well. But we are now responsible for creating the setter methods!
Ruby Attribute Accessor: attr_writer
The attr_writer is pretty much the opposite of attr_reader! Basically, we get all the instance variables and the setter methods, but there won’t be any getter method anymore!
For this reason, we’re responsible for creating the getter methods if we want objects to access the value of the instance variables.
Ruby attr_writer Syntax:
attr_writer :variable_name
Example: using attr_writer in Ruby
class Person attr_writer :first_name, :last_name, :id def first_name return "The name is: #{@first_name}" end def last_name return "The last name is: #{@last_name}" end def id return "The id is: #{@id}" end end prs = Person.new prs.first_name = "John" prs.last_name = "Doe" prs.id = 43 puts prs.first_name, prs.last_name, prs.id
Output:
The name is: John The last name is: Doe The id is: 43