Photo by Petrebels on Unsplash

Attributes in Ruby

Tech - RubyCademy
RubyCademy
Published in
3 min readApr 2, 2018

--

In this article, we’re going to explore the following topics:

  • the attr method
  • the attr_reader method
  • the attr_writer method
  • the attr_accessor method
  • lazy initialization

Introduction

In OOP, the concept ofmember access control is important as it allows control of the access to encapsulated variables.

In many programming languages, this concept is implemented by using getters and setters for each member.

In Ruby, the attr_* methods are in charge of the member access control.

attr

attr creates an instance variable and a getter method for each attribute name passed as an argument.

An argument can be a Symbol or a String that will be converted to Symbol

module Attr
attr :attr1, 'attr2'
end
irb> Attr.instance_methods
=> [:attr1, :attr2]

In the above example, the module Attr includes 2 instance methods that allow reading the value of attr1 and attr2.

attr_reader

attr_reader is similar to attr

module Attr
attr_reader :attr1, 'attr2'
end
irb> Attr.instance_methods
=> [:attr1, :attr2]

attr_writer

attr_writer creates an instance variable and a setter method for each attribute name passed as an argument.

An argument can be a Symbol or a String that will be converted to Symbol

module Attr
attr_writer :attr1, 'attr2'
end
irb> Attr.instance_methods
=> [:attr1=, :attr2=]

In the above example, the moduleAttr includes 2 instance methods that allow modifying the value of attr1 and attr2.

attr_accessor

attr_accessor creates an instance variable, a getter, and a setter method for each attribute name passed as an argument.

An argument can be a Symbol or a String that will be converted to Symbol

module Attr
attr_accessor :attr1, 'attr2'
end
irb> Attr.instance_methods.sort
=> [:attr1, :attr1=, :attr2, :attr2=]

In the above example, the module Attr includes 4 instance methods that allow to read and modify the value of attr1 and attr2.

Lazy Initialization

In the previous examples, I told you the attr_* methods create instance variables. It’s almost true.

Indeed, the instance variables created by the attr_* methods use thelazy initialization mechanism.

This means that the instance variables are only initialized when the setter method is invoked — or when the instance variable is explicitly set within an instance method

class Website
attr_accessor :link, :title
def initialize
@title = "The best Ruby newsletter"
end
end
irb> website = Website.new
=> #<Website:0x00777 @title="The best Ruby newsletter">
irb> website.instance_variables
=> [:@title]
irb> website.link = "http://ruby.devscoop.fr"
=> "http://ruby.devscoop.fr"
irb> website.instance_variables
[:@title, :@link]

In the above example, the instance variable@title is explicitly created in the Website#initialize method.

So, this instance variable is available in the array returned by the first call to instance_variables.

Notice that @link is not yet created, despite the call to attr_accessor. This instance variable is only created after the call to Website#link=.

So, by using the attr_* methods, the instance variable associated with each argument name will only be created when we set a value to it (by using the setter method or by explicitly assigning a value to it).

Ruby Mastery

We’re currently finalizing our first online course: Ruby Mastery.

Join the list for an exclusive release alert! 🔔

🔗 Ruby Mastery by RubyCademy

Also, you can follow us on x.com as we’re very active on this platform. Indeed, we post elaborate code examples every day.

💚

--

--