This content has been automatically translated from Ukrainian.
In Ruby attr_accessor is a macro (or method) for automatically creating a getter (value access method) and a setter (value setting method) for instance variables in a class.
For example:
class Cat end cat = Cat.new cat.name # => no method error
We don't have a method name in class Cat. Obviously we get no method error.
Let's try to add getter:
class Cat
def name
@name # returns the @name instance variable
end
end
cat = Cat.new
cat.name # => nil
Something seems to have gone wrong. But everything is correct. Getter cat.name returns nil. There is no longer a 'no method error' error, meaning the method exists, and returns the @name variable of the Cat instance. But this variable is empty. nil is the expected result.
In Ruby getter it is a method that allows you to get the value of the instance variable in the class. Getters are so called because they allow "receiving" (get) value of variable.
In Ruby, getters are usually used to provide access to variable values from outside the class, as variables are usually private and not directly accessible. Getters allow controlled access to these values.
Trying to use the setter gives an error no method error:
cat.name = 'Ruby'# => no method error
This is also an expected result. We don't have a method setter for name.
In Ruby, the setter is a method that allows you to set the value of the instance variable in the class. Setters are so called because they allow "install" (set) (or change existing) variable values.
In Ruby, setters are used to change variable values from outside the class in a controlled manner.
class Cat
def name
@name # returns the @name instance variable
end
def name=(str)
@name = str
end
end
Let's create an instance of Cat and call the name method:
cat = Cat.new cat.name # => nil
Everything is correct here. Our copy is currently empty. We need to pass the value using our new method (setter).
cat.name = 'Ruby'
We do not see any mistake. So let's try to use the getter method to extract the value:
cat.name # => Ruby
Everything works. But imagine that your class has not only name, but dozens of different attributes (age, color, etc.). It is not very convenient to write getter and setter methods every time.
So Ruby has some abbreviations (attr_reader and attr_writer):
class Cat attr_reader:name attr_writer:name end
:name - the name of the attribute for which the method is created.
attr_reader is a contraction for the getter method:
def name @name # returns the @name instance variable end
attr_writer is a shortcut for the method setter:
def name=(str) @name = str end
But when we need both methods - setter and getter, attr_reader and attr_writer need to duplicate them for each attribute:
class Cat attr_reader:name attr_writer:name attr_reader:color attr_writer:color end
It's more local than writing methods in full, but Ruby allows you to shorten this code as well. here we need attr_accessor.
class Cat attr_accessor:name attr_accessor:color end
Equivalent to the entry:
class Cat attr_reader:name attr_writer:name attr_reader:color attr_writer:color end
Usage attr_accessor, attr_reader and attr_writer makes it easy to create methods to access variables in classes, and it's especially convenient when you just need to get or set the value of a variable, without additional logic.
Ruby allows you to shorten what you seem to have already shortened. Here is a variant of abbreviated attribute writing via comma:
attr_reader :name, :color
This post doesn't have any additions from the author yet.