A method called ** attr_accessor ** that appears frequently when looking at the basic grammar of Ruby.
When I first saw it, I didn't know what it was used for when I entered from Ruby on Rails.
I'll look it up from there
-** Method that handles both setter and getter ** -** Refer to and change the value of the instance variable **
To be honest, I can't understand ...
For those who know it, it may be too prescriptive to say what it is, but if anyone stumbles at the same place as me, I would appreciate it if you could refer to it.
First of all, the ** attr_accessor ** method in question, but in a nutshell, it is a method ** that gives an instance an attribute that can be referenced and updated from the outside.
I will explain each one.
It's easy to forget when using Rails, but the main premise is that you can't directly access the values of ** instances. ** **
As an example, we have prepared the ** Hoge ** class below. There are two instance variables, ** name ** and ** age **.
attr_accessor.rb
class Hoge
def initialize(name, age)
@name = name
@age = age
end
def hello
p "Hello! I'm #{@name} "
p "I'm #{@age} old"
end
end
hoge = Hoge.new("hogehoge",12)
hoge.hello
p hoge.name
In this state, when I try to output the name which is a variable of hoge which is an instance of Hoge ...
"Hello! I'm hogehoge "
"I'm 12 old"
Traceback (most recent call last):
attr_accessor.rb:33:in `<main>': undefined method `name' for #<Hoge:0x0000000004e68eb8 @name="hogehoge", @age=12> (NoMethodError)
And NoMethodError occurs.
That should be it. This is because there is no method called name in the Hoge class.
Methods such as ** setter ** and ** getter ** come up to solve the problem of not being able to access the values of these instances.
Getters are used when you want to refer to the value of an instance as before. There are two ways to set getters: ** How to define methods ** and ** How to use access methods **.
The method of defining the method is really simple
python
class Hoge
def initialize(name, age)
@name = name
@age = age
end
#Realize value reference by using the same name as the instance variable
def name
name = @name
end
def hello
p "Hello! I'm #{@name} "
p "I'm #{@age} old"
end
end
Define a method that pulls an instance variable when executed.
However, this is a little uncool, so it is better to use the access method.
python
class Hoge
attr_reader :name
def initialize(name, age)
@name = name
@age = age
end
def hello
p "Hello! I'm #{@name} "
p "I'm #{@age} old"
end
end
You can refer to the value of the instance variable as above by using the ** attr_reader ** method. The value defined at this time must be ** the same as the one defined in the instance variable **.
This is the role of a getter to refer to the value.
Now that you can refer to the value, try substituting another value for the instance value in the same way as Rails ...
python
class Hoge
attr_reader :name
def initialize(name, age)
@name = name
@age = age
end
def hello
p "Hello! I'm #{@name} "
p "I'm #{@age} old"
end
end
hoge = Hoge.new("hogehoge",12)
hoge.hello
p hoge.name
hoge.name = "fugafuga"
--------------------------------------------------------------------------------
"Hello! I'm hogehoge "
"I'm 12 old"
"hogehoge"
Traceback (most recent call last):
attr_accessor.rb:37:in `<main>': undefined method `name=' for #<Hoge:0x0000000004fbb040 @name="hogehoge", @age=12> (NoMethodError)
Did you mean? name
I will get angry again.
This is because ** getters can see values, but they can't assign new values because they don't include the ability to update **.
What is used to solve this problem is called a ** setter **.
There are two types of setters, one is to define the method as it is and the other is to use the accessor method.
python
def name=(name)
@name = name
end
If you add ** = ** after the method, it becomes a setter. The content is simple, just reflect the received argument in the instance variable.
How to use accessor methods.
python
class Hoge
attr_reader :name
attr_writer :name
def initialize(name, age)
@name = name
@age = age
end
def hello
p "Hello! I'm #{@name} "
p "I'm #{@age} old"
end
end
The accessor method uses ** attr_writer **.
python
hoge = Hoge.new("hogehoge",12)
hoge.hello
p hoge.name
hoge.name = "fugafuga"
hoge.hello
------------------------------------------------------
"Hello! I'm hogehoge "
"I'm 12 old"
"hogehoge"
"Hello! I'm fugafuga "
"I'm 12 old"
And surely the value of name has been updated.
attr_accessor
It is finally the explanation of attr_accessor, but the role of this method is to be ** responsible for both getter and setter above.
In other words, you don't have to write two types, attr_reader and attr_writer
python
class Hoge
#This party plays the role of getter and setter
attr_accessor :name
def initialize(name, age)
@name = name
@age = age
end
def hello
p "Hello! I'm #{@name} "
p "I'm #{@age} old"
end
end
hoge = Hoge.new("hogehoge",12)
hoge.hello
p hoge.name
hoge.name = "fugafuga"
hoge.hello
----------------------------------------------------------
Hello! I'm hogehoge "
"I'm 12 old"
"hogehoge"
"Hello! I'm fugafuga "
"I'm 12 old"
Can be written fairly simply.
You may have wondered if you've read this far, but Rails usually doesn't show this accessor method.
Then, the reason why the table value can be referenced and updated like a method is because it is set automatically by ** ActiveRecord :: Base **.
If you like, I have written an article about that as well, so please have a look. >> rails db: migrate and the existence of models
This is the explanation of attr_accessor.
Method | function | role |
---|---|---|
attr_reader | Getter | You will be able to refer to the value of the instance variable |
attr_writer | Setter | You will be able to update the value of an instance variable |
attr_accessor | Getter setter | You will be able to refer to and update the values of instance variables |
Ruby on Rails is a very useful framework, but I strongly felt that I had to re-learn the basics of Ruby from time to time ...
We encourage you to write your own code about the contents of this area!
Well then
Recommended Posts