One of the classic mistakes in Ruby beginner articles is that attr_accessor
is called an" accessor ".
It seems that there are cases where the wording is simply wrong, and there are cases where it is not understood correctly in the first place.
In the case of Ruby, the accessor is
It is a general term for. Let's look at a typical example below
class Person
def name
@name
end
def name=(name)
@name = name
end
end
a_person = Person.new
a_person.name = "Kaoru"
puts a_person.name # => "Kaoru"
I have defined two methods, where name
is the getter andname =
is the setter. These two are collectively called an accessor.
As a convention
@
@
, with =
added to the end.(It's a convention, not a rule).
Methods whose names end in =
are called "assignment methods" and are treated a bit specially in Ruby syntax.
In the above example
a_person.name = "Kaoru"
As I wrote, you can put a space before =
when calling a method.
The code above is a type of assignment expression [^ ae].
[^ ae]: Ruby's assignment expressions are not limited to assignments to variables.
Not only that. You can also write a self-assignment expression using the assignment method. Let's look at the code below (assuming the class definition is as above).
a_person = Person.new
# (1)
a_person.name ||= "Kaoru"
puts a_person.name # => "Kaoru"
# (2)
a_person.name ||= "Haruka"
puts a_person.name # => "Kaoru"
(1)Now, instance variables@name
Has not yet been set to (when read)nil
Self-assignment operator in the state||=
Because I am using@name
The value of"Kaoru"
Will be.
However, in (2), the assignment does not occur because the string object is assigned to @ name
. Therefore, the return value of a_person.name
is"Kaoru"
instead of"Haruka"
.
Pretending to be longer. Let's get into the main subject from here. Looking at the class definition above, the getter and setter definitions spend three lines each (albeit simple). If you have 5 instance variables and you want to define a getter and a setter for each, you'll need 30 lines. This is ridiculous.
So, if you want to define such a simple getter or setter, [^ simp]
class Person
attr_accessor :name
end
You just have to write.
[^ simp]: There is a reason I wrote "simple". Sometimes you want to define a non-simple accessor. Especially in the case of setters, you may want to apply some normalization (such as unifying full-width / half-width characters or deleting extra spaces) to a given argument before assigning it to an instance variable. In such cases, attr_accessor
cannot be used.
I often see articles that describe this attr_accessor
as an" accessor ".
However, attr_accessor
defines an accessor, not an accessor in itself.
Perhaps even though part of the name has "accessor", it is dragged and thinks it is "accessor".
By the way, who is attr_accessor
?
If you come from another language, you might think it's part of Ruby's class definition syntax, but there's no such grammar.
attr_accessor
is just a method.
Reference: Module # attr_accessor (Ruby 3.0.0 Reference Manual)
In other words
attr_accessor :name
Is just calling the method attr_accessor
with the symbol: name
as an argument.
This will define the accessor in the class.
attr_accessor
is a method ** that defines a ** method.
To supplement a little
class Person
~ end
), the class is self
.about it. Here's the code to check the last point:
class Hoge
p name # => "Hoge"
end
In this code, name
is not a local variable. Since there is no assignment expression to name
before this point, it cannot be a local variable.
Then it should be a method call.
The receiver is not written in this method call.
Since this is in a class definition expression, the receiver for name
is the Hoge
class.
Since Hoge
is an instance of a class called Class
, name
is a method that returns the class name / module name. So you will see "Hoge "
.
Reference: Module # inspect (Ruby 3.0.0 Reference Manual)
If you can understand the above,
class Person
attr_accessor :name
end
Is
class Person
end
Person.attr_accessor(:name)
You will find that it is the same as writing.
Recommended Posts