Ruby Attribute Accessor Methods Tutorial

  • Post author:
  • Post category:Ruby

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

Leave a Reply