[RUBY] Je suis entré depuis Rails et je ne savais pas ce qu'était [attr_accessor]

Une méthode appelée ** attr_accessor ** qui apparaît fréquemment lorsque l'on regarde la grammaire de base de Ruby.

Quand je l'ai vu pour la première fois, je ne savais pas à quoi il servait lorsque je suis entré depuis Ruby on Rails.

Je vais chercher à partir de là

Pour être honnête, je ne comprends pas ...

Pour ceux qui le connaissent, il est peut-être trop normatif de dire ce que c'est, mais si quelqu'un trébuche au même endroit que moi, j'apprécierais que vous puissiez vous y référer.

Utilisation de attr_accessor

Tout d'abord, la méthode ** attr_accessor ** en question, mais en un mot, c'est une méthode ** qui donne à l'instance un attribut qui peut être référencé et mis à jour de l'extérieur.

Je vais expliquer un par un.

Vous ne pouvez pas accéder directement à la valeur de l'instance

Il est facile d'oublier lors de l'utilisation de Rails, mais le principe principal est que vous ne pouvez pas accéder directement aux valeurs des instances **. ** **

A titre d'exemple, nous avons préparé la classe ** Hoge ** ci-dessous. Il existe deux variables d'instance, ** name ** et ** 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

Dans cet état, quand j'essaye de sortir le nom, qui est une variable de hoge, qui est une instance de 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)

Et NoMethodError se produit.

Ça devrait être ça. C'est parce qu'il n'y a pas de méthode appelée nom dans la classe Hoge.

Les méthodes ** setter ** et ** getter ** viennent résoudre le problème de ne pas pouvoir accéder aux valeurs de ces instances.

Getter

Le getter est utilisé lorsque vous souhaitez faire référence à la valeur de l'instance comme auparavant. Il existe deux façons de définir le getter: ** Comment définir une méthode ** et ** Comment utiliser une méthode d'accès **.

La façon de définir une méthode est vraiment simple

python


class Hoge

  def initialize(name, age)
    @name = name
    @age = age
  end
 
 #Réaliser une référence de valeur en utilisant le même nom que la variable d'instance
  def name
    name = @name
  end

  def hello
    p "Hello! I'm #{@name} "
    p "I'm #{@age} old"
  end
end

Définissez une méthode qui extrait la variable d'instance lorsqu'elle est exécutée.

Cependant, ce n'est pas cool, il est donc préférable d'utiliser la méthode d'accès.

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

Vous pouvez faire référence à la valeur de la variable d'instance comme ci-dessus en utilisant la méthode ** attr_reader **. La valeur définie à ce stade doit être ** la même que celle définie dans la variable d'instance **.

C'est le rôle du getter de faire référence à la valeur.

Setter

Maintenant que vous pouvez faire référence à la valeur, essayez de remplacer la valeur de l'instance par une autre valeur de la même manière que 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

Je vais me fâcher à nouveau.

En effet, les ** getters peuvent voir les valeurs, mais ils ne peuvent pas attribuer de nouvelles valeurs car ils n'incluent pas la possibilité de mettre à jour **.

Ce qui est utilisé pour résoudre ce problème s'appelle ** setter **.

Il existe deux types de setters, l'un consiste à définir la méthode telle quelle et l'autre à utiliser la méthode accesseur.

python


def name=(name)
    @name = name
end

Si vous ajoutez ** = ** après la méthode, cela devient un setter. Le contenu est simple, il suffit de refléter l'argument reçu dans la variable d'instance.

Comment utiliser la méthode accesseur.

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

La méthode d'accesseur utilise ** 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"

Et sûrement la valeur du nom a été mise à jour.

attr_accessor

C'est finalement l'explication de attr_accessor, mais le rôle de cette méthode est d'être ** responsable à la fois du getter et du setter ci-dessus.

En d'autres termes, vous n'avez pas besoin d'écrire deux types, attr_reader et attr_writer

python


class Hoge
  #Cette fête joue le rôle de getter et de 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"

Peut être écrit assez simplement.

Vous vous êtes peut-être demandé si vous aviez lu jusqu'ici, mais Rails ne montre généralement pas cette méthode d'accesseur.

Ensuite, la raison pour laquelle la valeur de la table peut être référencée et mise à jour comme une méthode est qu'elle est définie automatiquement par ** ActiveRecord :: Base **.

Si vous le souhaitez, j'ai également écrit un article à ce sujet, alors jetez un œil. >> rails db: migrer et l'existence de modèles

C'est l'explication de attr_accessor.

Résumé

Méthode une fonction rôle
attr_reader Getter Vous pourrez vous référer à la valeur de la variable d'instance
attr_writer Setter Vous pourrez mettre à jour la valeur de la variable d'instance
attr_accessor Setter Setter Vous pourrez voir et mettre à jour les valeurs des variables d'instance

Ruby on Rails est un framework très utile, mais j'ai fortement senti que parfois je devais réapprendre les bases de Ruby ...

Nous vous encourageons à écrire votre propre code sur le contenu de cette zone!

Eh bien

Recommended Posts

Je suis entré depuis Rails et je ne savais pas ce qu'était [attr_accessor]
Ce que j'ai appris en étudiant les rails
Je savais ce qu'était la réflexion
Ce à quoi j'étais accro en utilisant rspec sur des rails
J'ai été surpris que Rails le fasse automatiquement.
Une note de ce sur quoi j'ai trébuché et remarqué en rattrapant Laravel de Rails
Ce à quoi j'étais accro lors de la mise en œuvre de l'authentification Google avec des rails
[Rails] Quel était le message d'erreur?
[Rails] Ce que j'ai appris d'une petite pierre d'achoppement lors de l'utilisation de l'ascendance
Ce que j'ai appris du calcul monétaire Java
Je ne savais pas quoi écrire dans la portée de Maven, alors j'ai cherché.