Ruby a ce moyen pratique et pratique de partager des variables d'instance en utilisant des clés comme
attr_accessor :var
attr_reader :var
attr_writer :var
Pourquoi devrais-je choisir attr_reader
ou attr_writer
si je pouvais simplement utiliser attr_accessor
? Y a-t-il quelque chose comme la performance (dont je doute)? Je suppose qu'il y a une raison, sinon ils n'auraient pas fait de telles clés.
Réponses:
Vous pouvez utiliser les différents accesseurs pour communiquer votre intention à quelqu'un qui lit votre code et faciliter l'écriture de classes qui fonctionneront correctement quel que soit le nom de leur API publique.
Ici, je peux voir que je peux lire et écrire l'âge.
Ici, je peux voir que je ne peux lire que l'âge. Imaginez qu'il soit défini par le constructeur de cette classe et qu'ensuite il reste constant. S'il y avait un mutateur (écrivain) pour l'âge et que la classe était écrite en supposant que l'âge, une fois défini, ne change pas, un bogue pourrait résulter du code appelant ce mutateur.
Mais que se passe-t-il en coulisses?
Si vous écrivez:
Cela se traduit par:
Si vous écrivez:
Cela se traduit par:
Si vous écrivez:
Cela se traduit par:
Sachant cela, voici une autre façon de penser: si vous n'aviez pas les assistants attr _... et deviez écrire les accesseurs vous-même, écririez-vous plus d'accesseurs que votre classe n'en avait besoin? Par exemple, si l'âge devait seulement être lu, écririez-vous également une méthode permettant de l'écrire?
la source
attr_reader :a
rapport àdef a; return a; end
confreaks.net/videos/…attr_reader
accesseur défini prend 86% du temps que l'accesseur défini manuellement. Pour Ruby 1.9.0, l'attr_reader
accesseur défini prend 94% du temps que l'accesseur défini manuellement. Dans tous mes tests, cependant, les accesseurs sont rapides: un accesseur prend environ 820 nanosecondes (Ruby 1.8.7) ou 440 nanosecondes (Ruby 1.9). À ces vitesses, vous devrez appeler un accesseur des centaines de millions de fois pour que les performancesattr_accessor
améliorent l'exécution globale d'une seconde.attr_accessor :a, :b
Toutes les réponses ci-dessus sont correctes;
attr_reader
etattr_writer
sont plus pratiques à écrire qu’à taper manuellement les méthodes pour lesquelles ils sont des raccourcis. En dehors de cela, ils offrent des performances bien meilleures que l'écriture de la définition de la méthode vous-même. Pour plus d'informations, voir la diapositive 152 à partir de cette présentation ( PDF ) d'Aaron Patterson.la source
Tous les attributs d'un objet ne sont pas censés être définis directement depuis l'extérieur de la classe. Avoir des rédacteurs pour toutes vos variables d'instance est généralement un signe de faible encapsulation et un avertissement que vous introduisez trop de couplage entre vos classes.
À titre d'exemple pratique: j'ai écrit un programme de conception où vous placez des articles dans des conteneurs. L'article avait
attr_reader :container
, mais cela n'avait aucun sens d'offrir un écrivain, car la seule fois où le conteneur de l'article devrait changer, c'est quand il est placé dans un nouveau, ce qui nécessite également des informations de positionnement.la source
Il est important de comprendre que les accesseurs restreignent l'accès aux variables, mais pas à leur contenu. En ruby, comme dans certains autres langages OO, chaque variable est un pointeur vers une instance. Ainsi, si vous avez un attribut à un hachage, par exemple, et que vous le définissez en "lecture seule", vous pouvez toujours changer son contenu, mais pas le contenu du pointeur. Regarde ça:
Comme vous pouvez le voir, il est possible de supprimer une paire clé / valeur de Hash @a, comme ajouter de nouvelles clés, modifier des valeurs, eccetera. Mais vous ne pouvez pas pointer vers un nouvel objet car il s'agit d'une variable d'instance en lecture seule.
la source
Vous ne voulez pas toujours que vos variables d'instance soient entièrement accessibles depuis l'extérieur de la classe. Il y a de nombreux cas où autoriser l'accès en lecture à une variable d'instance est logique, mais il peut ne pas y écrire (par exemple, un modèle qui récupère des données à partir d'une source en lecture seule). Il y a des cas où vous voulez le contraire, mais je ne peux penser à aucun qui ne soit artificiel du haut de ma tête.
la source