Attributes in Ruby
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'
endirb> 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'
endirb> 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'
endirb> 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'
endirb> 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
endirb> 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).
RubyCademy’s Newsletter
In the RubyCademy newsletter, I share what I’m learning about Ruby & Rails, including helpful tips, code insights, and exclusive Ruby Cards with detailed explanations.
If it sounds helpful, feel free to subscribe for free:
Thank you for taking the time to read this message!