Comment utiliser des variables globales ou des valeurs constantes en Ruby?
J'ai un programme qui ressemble à:
$offset = Point.new(100, 200);
def draw(point)
pointNew = $offset + point;
drawAbsolute(point)
end
draw(Point.new(3, 4));
l'utilisation de $offset
semble un peu bizarre.
En C, si je définir quelque chose en dehors de toute fonction, il est une variable globale automatiquement. Pourquoi Ruby-t-il $offset
mais ne peut pas être offset
et encore être global? Si c'est offset
, alors c'est un local? Mais local où, parce qu'il se sent très bien mondiale.
Sont t-il de meilleures façons d'écrire le code ci-dessus? L'utilisation de $offset
peut sembler un peu moche au premier abord.
Mise à jour: je peux mettre ce décalage à l'intérieur d'un class
définition, mais que faire si deux ou plusieurs classes ont besoin d'utiliser cette constante? Dans ce cas, dois-je encore besoin de définir un $offset
?
- Venant de C, vous pourriez ne pas savoir cela, mais vous n'avez pas besoin de mettre de la semi-points sur la fin de vos lignes de Rubis. Vous avez seulement besoin d'utiliser, pour séparer plusieurs instructions sur la même ligne, par exemple "a = 5; b = 10"
Vous devez vous connecter pour publier un commentaire.
Une chose que vous devez comprendre, c'est en Ruby, tout est un objet. Étant donné que, si vous ne définissez pas vos méthodes dans
Module
ouClass
, Ruby va le mettre dans leObject
classe. Ainsi, votre code sera locale à laObject
portée.Une approche typique sur la Programmation Orientée Objet est d'encapsuler toute logique au sein d'une classe:
Espère que cela clarifie un peu.
Object
portée: c'est vrai pour les variables sans les$
préfixe, mais, en revanche, méthode vous y mettre est global (tout en devenant des membres privés de laObject
classe).Point
objets sont en conformité avec un certain décalage constant, alors je peux avoir un décalage (x, y) comme une constante de classe, de sorte que ledraw_absolute()
va utiliser cette constante de classe comme un décalageDe la portée des variables en Ruby, c'est contrôlée par des sceaux à un certain degré. Les Variables commençant par
$
sont globales, variables avec@
sont les variables d'instance,@@
moyens de variables de classe, et les noms commençant par une majuscule sont des constantes. Toutes les autres variables sont des locaux. Lorsque vous ouvrez une classe ou d'une méthode, c'est un nouveau champ d'application, et les locaux disponibles dans l'ancien périmètre ne sont pas disponibles.En général, je préfère éviter de créer des variables globales. Il existe deux techniques généralement d'atteindre le même objectif que je considère comme nettoyant:
Créer une constante dans un module. Donc, dans ce cas, vous devez mettre toutes les classes qui ont besoin de l'offset dans le module
Foo
et créer une constanteOffset
, alors toutes les classes d'accèsFoo::Offset
.Définir une méthode pour accéder à la valeur. Vous pouvez définir la méthode à l'échelle mondiale, mais encore une fois, je pense que c'est mieux de l'encapsuler dans un module ou d'une classe. De cette façon, les données sont disponibles là où vous en avez besoin et vous pouvez même modifier si vous avez besoin, mais la structure de votre programme et de la propriété des données sera plus clair. Ce n'est plus en ligne avec les principes de conception OO.
Une des raisons pour lesquelles la variable globale a besoin d'un préfixe (appelé un "sceau"), c'est parce qu'en Ruby, contrairement au C, vous n'avez pas à déclarer les variables avant de les assigner à eux. Le sceau est utilisé comme un moyen d'être explicite quant à la portée de la variable.
Sans un préfixe spécifique pour les variables globales, un relevé
pointNew = offset + point
à l'intérieur de votredraw
méthode, puisoffset
fait référence à une variable locale à l'intérieur de la méthode (et les résultats dans unNameError
dans ce cas). La même pour@
utilisé pour faire référence à des variables d'instance et@@
pour les variables de classe.Dans d'autres langues que l'utilisation des déclarations explicites tels que
C
,Java
etc. le placement de la déclaration est utilisée pour contrôler la portée.$
aider Ruby savoir si c'est une nouvelle variable ou existant? Si vous assigner quelque chose à$foo
en pensant que certains$foo
, mais il se trouve qu'il n'est pas tout$foo
encore, ou il était mais quelqu'un l'a enlevé, puis Ruby va créer$foo
comme une nouvelle néanmoins, en dépit ce n'est pas la même$foo
que vous avez pensé.$
ne sera pas réparer l'absence de déclarations.Je pense que c'est local pour le fichier que vous avez déclarée à l'offset. Considérer chaque fichier pour être une méthode en soi.
Peut-être mettre le tout dans une classe, puis en faire décalage d'une variable de classe avec
@@offset = Point.new(100, 200);
?