C'est une erreur commune faite par les codeurs Java venant aussi à Ruby, et l'un des grands sauts conceptuels que j'ai dû faire pour comprendre. Au début, cela semble étrange, mais c'est vraiment l'un des aspects les plus cool de Ruby - tout le code est exécutable, y compris les définitions de classe. Par conséquent, les variables d'instance doivent être déclarées à l'intérieur des méthodes. Cela a à voir avec la façon dont le «soi» est évalué. 'self' est l'objet courant. L'interprète rechercher les appels de méthodes et références variables d'abord dans « soi »:
class Fish
@var = "foo" # here 'self' == Fish, the constant which contains the class object
def foo
# do foo
end
end
fish = Fish.new
fish.foo # here 'self' == fish, an instance of Fish
Dans une définition de classe, « soi » est défini comme l'objet de classe étant définie, de sorte que toutes les références dans une définition de classe se référeront à cet objet de classe, dans ce cas poisson.
Lorsqu'une méthode est appelée sur une instance de Fish, self est défini comme étant le destinataire de l'appel, l'instance particulière de Fish. Donc, en dehors d'une définition de méthode, self est l'objet de classe. À l'intérieur d'une méthode, self est l'instance du récepteur. C'est pourquoi @var en dehors d'une définition de méthode ressemble plus à une variable statique en Java, et @var à l'intérieur d'une définition de méthode est une variable d'instance.
shouldn » t que ce soit un @@ var dans le premier bloc de code? – Jean
Je lis "The Well-Grounded Rubyist" (http://manning.com/black2/) par David Black. Il fait un excellent travail en expliquant toutes les nuances dans ce domaine. –
Jean: Non. Si j'utilisais @@ var' alors les sous-classes remplaceraient les classes parentes. Voir le lien de hobodave. Spécifiquement, comment '2' est remplacé dans l'exemple. –