Dans Ruby, dans le cadre d'une méthode de classe, quelles sont les variables instance et la classe?
-
25-09-2019 - |
Question
Si j'ai la pièce de code suivante Ruby:
class Blah
def self.bleh
@blih = "Hello"
@@bloh = "World"
end
end
Quels sont exactement @blih et @@ Bloh? @blih est une variable d'instance dans la Blah classe, et @@ Bloh est une variable de classe dans la classe Blah, correct? Est-ce que cela signifie que Bloh de @@ est une variable dans la classe de Blah, classe?
La solution
Les gens semblent ignorer que la méthode est une méthode de classe.
@blih sera variable d'instance de l'instance de classe de classe pour la Bleh constante. Par conséquent:
irb(main):001:0> class Bleh
irb(main):002:1> def self.bleh
irb(main):003:2> @blih = "Hello"
irb(main):004:2> @@blah = "World"
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> Bleh.instance_variables
=> []
irb(main):008:0> Bleh.bleh
=> "World"
irb(main):009:0> Bleh.instance_variables
=> ["@blih"]
irb(main):010:0> Bleh.instance_variable_get :@blih
=> "Hello"
@@ blah sera disponible en tant que variable de classe de Bleh:
irb(main):017:0> Bleh.class_variables
=> ["@@blah"]
irb(main):018:0> Bleh.send :class_variable_get, :@@blah
=> "World"
Autres conseils
Il y a une méthode à cette folie ...
class Example
@foo # class instance variable
@@bar # class variable
def fun1
@baz # instance variable
end
end
Les variables d'instance
Les variables d'instance (@foo
et @baz
dans l'exemple) commencent toujours par @
et ils ont toujours appartiennent à quel que soit l'auto objet fait référence à : soit un objet de la classe, ou l'objet de classe représentant une classe. Une instance de référence variable dans une méthode définition de classe ou classe est complètement différente d'une instance de référence variable dans une méthode d'instance.
Héritage Étant donné que les variables d'instance ne sont pas définies par une classe, ils ne sont pas liés au mécanisme d'héritage -Ils sont tout simplement créé lorsqu'une valeur est affectée. variables d'instance de classe, étant simplement des variables d'instance de l'objet de classe qui représente une classe, ne sont donc pas hérité.
Les variables de classe
Les variables de classe sont visibles et partagés par les méthodes de classe et les méthodes d'instance d'une classe, et aussi par la définition de la classe elle-même. Les variables de classe peuvent être utilisés dans les méthodes d'instance, les méthodes de classe et dans la définition de la classe elle-même, en dehors de toute méthode. Les variables de classe sont toujours évaluées en référence à l'objet de classe créée par l'instruction de définition de classe englobante .
Variable variable d'instance de classe vs instance
Un inconvénient des variables d'instance de classe est qu'ils ne peuvent pas être utilisés dans les méthodes d'instance comme variables de classe peuvent. Un autre inconvénient est le risque de les confondre avec les variables d'instance ordinaires. Un avantage de variables d'instance de classe sur les variables de classe a à voir avec le comportement déroutant des variables de classe lorsque le sous-classement d'une classe existante: si une classe utilise des variables de classe, toute sous-classe peut modifier le comportement de la classe et tous ses descendants en changeant la valeur de la variable de classe partagée. Ceci est un argument fort pour l'utilisation de variables d'instance de classe au lieu de variables de classe.
Une variable préfixée par deux à des signes est une variable de classe, accessible au sein des deux instances et des méthodes de la classe de la classe.
Exemple:
class CountEm
@@children = 0
def initialize
@@children += 1
@myNumber = @@children
end
def whoAmI
"I'm child number #@myNumber (out of #@@children)"
end
def CountEm.totalChildren
@@children
end
end
c1 = CountEm.new
c2 = CountEm.new
c3 = CountEm.new
c1.whoAmI # -> "I'm child number 1 (out of 3)"
c3.whoAmI # -> "I'm child number 3 (out of 3)"
CountEm.totalChildren # -> 3
Exemple tiré de texte du lien
[modifié pour plus de clarté]
Dans votre exemple de réglage @blih ne seront pas visibles en dehors de la portée de votre méthode de classe, car à l'intérieur d'une méthode de classe il n'y a pas d'exemple pour lier une variable d'instance à elle.
En parlant de la terminologie, je dirais "@@ Bloh est variable de catégorie dans la classe Blah" mais pas "variable dans la classe de classe Blah". Classe "classe" reste intacte.