Que sont les variables Ruby précédées d'un double signe ( @@
)? Ma compréhension d'une variable précédée d'un signe arobase est qu'il s'agit d'une variable d'instance, comme celle-ci en PHP:
Version PHP
class Person {
public $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
Équivalent rubis
class Person
def set_name(name)
@name = name
end
def get_name()
@name
end
end
Que signifie le double signe @@
arobase et en quoi diffère-t-il d'un signe arobase unique?
@
intérieur desself
méthodes) et non des variables de classe (@@
). Voir la litanie des raisons dans les réponses ci-dessous.Réponses:
Une variable préfixée par
@
est une variable d'instance , tandis qu'une variable préfixée par@@
est une variable de classe . Consultez l'exemple suivant; sa sortie est dans les commentaires à la fin desputs
lignes:Vous pouvez voir que
@@shared
c'est partagé entre les classes; la définition de la valeur dans une instance de one change la valeur de toutes les autres instances de cette classe et même des classes enfants, là où une variable nommée@shared
, avec un@
, ne le serait pas.[Mettre à jour]
Comme le mentionne Phrogz dans les commentaires, c'est un idiome courant dans Ruby pour suivre les données au niveau de la classe avec une variable d'instance sur la classe elle-même . Cela peut être un sujet délicat à comprendre, et il y a beaucoup de lectures supplémentaires sur le sujet, mais pensez-y comme une modification de la
Class
classe, mais uniquement de l'instance de laClass
classe avec laquelle vous travaillez. Un exemple:J'ai inclus l'
Square
exemple (quels résultatsnil
) pour démontrer que cela peut ne pas se comporter à 100% comme prévu; l' article que j'ai lié ci-dessus contient de nombreuses informations supplémentaires sur le sujet.Gardez également à l'esprit que, comme pour la plupart des données, vous devez être extrêmement prudent avec les variables de classe dans un environnement multithread , comme indiqué par le commentaire de dmarkow.
la source
ruby class << self end
bloc, en particulier l'opérateur <<.class << self
voir ceci@
- Variable d'instance d'une classe@@
- Variable de classe, également appelée variable statique dans certains casUne variable de classe est une variable partagée entre toutes les instances d'une classe. Cela signifie qu'une seule valeur de variable existe pour tous les objets instanciés à partir de cette classe. Si une instance d'objet change la valeur de la variable, cette nouvelle valeur changera essentiellement pour toutes les autres instances d'objet.
Une autre façon de penser les variables de classe est celle des variables globales dans le contexte d'une seule classe. Les variables de classe sont déclarées en préfixant le nom de la variable avec deux
@
caractères (@@
). Les variables de classe doivent être initialisées au moment de la créationla source
@@
désigne une variable de classe, c'est-à-dire qu'elle peut être héritée.Cela signifie que si vous créez une sous-classe de cette classe, elle héritera de la variable. Donc, si vous avez une classe
Vehicle
avec la variable de classe,@@number_of_wheels
si vous créez une,class Car < Vehicle
elle aura aussi la variable de classe@@number_of_wheels
la source
Vehicle
avec la variable de classe,@@number_of_wheels
alors si vous créez une,class Car < Vehicle
elle aura aussi la variable de classe@@number_of_wheels
class Vehicle
avec@number_of_wheels
, alorsclass Car < Vehicle
aura également une variable d'instance appelée@number_of_wheels
. La principale différence avec les variables de classe est que les classes ont la même variable, par exemple, changer l'une change les autres.@ et @@ dans les modules fonctionnent également différemment lorsqu'une classe étend ou inclut ce module.
Tellement donné
Ensuite, vous obtenez les sorties ci-dessous affichées sous forme de commentaires
Utilisez donc @@ dans les modules pour les variables que vous voulez communes à toutes leurs utilisations, et utilisez @ dans les modules pour les variables que vous voulez séparer pour chaque contexte d'utilisation.
la source
Les réponses sont partiellement correctes car @@ est en fait une variable de classe qui est par hiérarchie de classes, ce qui signifie qu'elle est partagée par une classe, ses instances et ses classes descendantes et leurs instances.
Cela produira
Il n'y a donc qu'une seule variable @@ pour les classes Person, Student et Graduate et toutes les méthodes de classe et d'instance de ces classes font référence à la même variable.
Il existe une autre façon de définir une variable de classe qui est définie sur un objet de classe (rappelez-vous que chaque classe est en fait une instance de quelque chose qui est en fait la classe de classe mais c'est une autre histoire). Vous utilisez la notation @ au lieu de @@ mais vous ne pouvez pas accéder à ces variables à partir des méthodes d'instance. Vous devez avoir des wrappers de méthode de classe.
Ici, @people est unique par classe au lieu de la hiérarchie de classes car il s'agit en fait d'une variable stockée sur chaque instance de classe. Voici la sortie:
Une différence importante est que vous ne pouvez pas accéder à ces variables de classe (ou variables d'instance de classe que vous pouvez dire) directement à partir des méthodes d'instance, car @people dans une méthode d'instance ferait référence à une variable d'instance de cette instance spécifique des classes Person, Student ou Graduate .
Ainsi, alors que d'autres réponses indiquent correctement que @myvariable (avec une seule notation @) est toujours une variable d'instance, cela ne signifie pas nécessairement qu'il ne s'agit pas d'une seule variable partagée pour toutes les instances de cette classe.
la source