Voici un code:
class Person
def initialize(age)
@age = age
end
def age
@age
end
def age_difference_with(other_person)
(self.age - other_person.age).abs
end
protected :age
end
Ce que je veux savoir, c'est la différence entre utiliser @age
et self.age
dans la age_difference_with
méthode.
la source
La différence est qu'elle isole l'utilisation de la méthode de sa mise en œuvre. Si la mise en œuvre de la propriété devait changer - par exemple pour conserver la date de naissance, puis calculer l'âge en fonction de la différence de temps entre maintenant et la date de naissance - alors le code dépendant de la méthode n'a pas besoin de changer. S'il utilisait directement la propriété, la modification devrait se propager à d'autres zones du code. En ce sens, l'utilisation directe de la propriété est plus fragile que l'utilisation de l'interface fournie par la classe.
la source
Soyez averti lorsque vous héritez d'une classe à partir de
Struct.new
laquelle il existe un moyen efficace de générer un initiateur ( Comment générer un initialiseur dans Ruby? )class Node < Struct.new(:value) def initialize(value) @value = value end def show() p @value p self.value # or `p value` end end n = Node.new(30) n.show()
reviendra
30 nil
Cependant, lorsque vous supprimez l'initialiseur, il retournera
nil 30
Avec la définition de classe
class Node2 attr_accessor :value def initialize(value) @value = value end def show() p @value p self.value end end
Vous devez fournir le constructeur.
n2 = Node2.new(30) n2.show()
reviendra
30 30
la source
La première réponse est tout à fait correcte, mais en tant que débutant relatif, ce n'était pas immédiatement clair pour moi ce que cela impliquait (envoyer des messages à soi-même? Uh huh ...). Je pense qu'un court exemple aidera:
class CrazyAccessors def bar=(val) @bar = val - 20 # sets @bar to (input - 20) end def bar @bar end def baz=(value) self.bar = value # goes through `bar=` method, so @bar = (50 - 20) end def quux=(value) @bar = value # sets @bar directly to 50 end end obj = CrazyAccessors.new obj.baz = 50 obj.bar # => 30 obj.quux = 50 obj.bar # => 50
la source
Il n'y a aucune différence. Je soupçonne que cela a été fait uniquement pour la valeur documentaire de se voir
self.age
et de seother_person.age
rapprocher.Je suppose que l'utilisation permet d'écrire un getter réel dans le futur, ce qui pourrait faire quelque chose de plus complexe que de simplement renvoyer une variable d'instance, et dans ce cas, la méthode n'aurait pas besoin de changer.
Mais c'est une abstraction peu probable dont il faut se soucier, après tout, si l'implémentation de l'objet a changé, il est raisonnable de changer d'autres méthodes, à un moment donné, une simple référence dans l'objet lui-même est parfaitement raisonnable.
Dans tous les cas, l'abstraction de la
age
propriété n'explique toujours pas l'utilisation explicite deself
, car tout simplementage
aurait également invoqué l'accesseur.la source
@age - est définitivement l'âge de la variable d'instance
self.age - fait référence à l'âge de la propriété de l'instance.
la source